*Not available yet*
+
+If you simply want to test that ConE works correctly on your machine, you can
+also run:
+
+ * ``ant test``
+
+This will export the test set, install ConE and run the tests inside a temporary
+build directory in the working copy.
+
+Build and install debian packages (Maemo)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ 1. Install tools and cone dependencies, as root or with sudo.
+
+ * ``sudo apt-get install dpkg-dev fakeroot python-setuptools python-central``
+
+ 2. Build python-cone and cone-tool. The packages are placed in parent directory.
+
+ * ``cd cone/trunk``
+ * ``dpkg-buildpackage -rfakeroot -b``
+
+ 3. Install the binary packages, as root or with sudo.
+
+ * ``sudo dpkg -i ../python-cone*.deb ../cone-tool*.deb``
+
+ 4. Install Jinja2 (not part of all Debian-based distros)
+
+ * ``sudo easy_install Jinja2``
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/licence-configurationengine.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/licence-configurationengine.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+Eclipse Public License - Version 1.0
+
+
+
+
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
+AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial
+code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program
+originate from and are distributed by that particular Contributor. A
+Contribution 'originates' from a Contributor if it was added to the
+Program by such Contributor itself or anyone acting on such
+Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii)
+are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes
+the Program.
+
+"Licensed Patents" mean patent claims licensable by a
+Contributor which are necessarily infringed by the use or sale of its
+Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance
+with this Agreement.
+
+"Recipient" means anyone who receives the Program under
+this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free copyright license to reproduce, prepare derivative works
+of, publicly display, publicly perform, distribute and sublicense the
+Contribution of such Contributor, if any, and such derivative works, in
+source code and object code form.
+
+b) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free patent license under Licensed Patents to make, use, sell,
+offer to sell, import and otherwise transfer the Contribution of such
+Contributor, if any, in source code and object code form. This patent
+license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor,
+such addition of the Contribution causes such combination to be covered
+by the Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.
+
+c) Recipient understands that although each Contributor
+grants the licenses to its Contributions set forth herein, no assurances
+are provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it
+has sufficient copyright rights in its Contribution, if any, to grant
+the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code
+form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this
+Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors
+all warranties and conditions, express and implied, including warranties
+or conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors
+all liability for damages, including direct, indirect, special,
+incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this
+Agreement are offered by that Contributor alone and not by any other
+party; and
+
+iv) states that source code for the Program is available
+from such Contributor, and informs licensees how to obtain it in a
+reasonable manner on or through a medium customarily used for software
+exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each
+copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use of
+the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create
+potential liability for other Contributors. Therefore, if a Contributor
+includes the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and
+indemnify every other Contributor ("Indemnified Contributor")
+against any losses, damages and costs (collectively "Losses")
+arising from claims, lawsuits and other legal actions brought by a third
+party against the Indemnified Contributor to the extent caused by the
+acts or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In
+order to qualify, an Indemnified Contributor must: a) promptly notify
+the Commercial Contributor in writing of such claim, and b) allow the
+Commercial Contributor to control, and cooperate with the Commercial
+Contributor in, the defense and any related settlement negotiations. The
+Indemnified Contributor may participate in any such claim at its own
+expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable laws,
+damage to or loss of data, programs or equipment, and unavailability or
+interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the
+date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of time
+after becoming aware of such noncompliance. If all Recipient's rights
+under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this
+Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The
+Agreement Steward reserves the right to publish new versions (including
+revisions) of this Agreement from time to time. No one other than the
+Agreement Steward has the right to modify this Agreement. The Eclipse
+Foundation is the initial Agreement Steward. The Eclipse Foundation may
+assign the responsibility to serve as the Agreement Steward to a
+suitable separate entity. Each new version of the Agreement will be
+given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version
+of the Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
+rights or licenses to the intellectual property of any Contributor under
+this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and
+the intellectual property laws of the United States of America. No party
+to this Agreement will bring a legal action under this Agreement more
+than one year after the cause of action arose. Each party waives its
+rights to a jury trial in any resulting litigation.
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/license-jinja2-2.1.1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/license-jinja2-2.1.1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,44 @@
+ 1: Copyright (c) 2006-2008 by the respective authors (see AUTHORS file).
+ 2: All rights reserved.
+ 3:
+ 4: Redistribution and use in source and binary forms, with or without
+ 5: modification, are permitted provided that the following conditions are
+ 6: met:
+ 7:
+ 8: * Redistributions of source code must retain the above copyright
+ 9: notice, this list of conditions and the following disclaimer.
+ 10:
+ 11: * Redistributions in binary form must reproduce the above
+ 12: copyright notice, this list of conditions and the following
+ 13: disclaimer in the documentation and/or other materials provided
+ 14: with the distribution.
+ 15:
+ 16: * The names of the contributors may not be used to endorse or
+ 17: promote products derived from this software without specific
+ 18: prior written permission.
+ 19:
+ 20: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ 21: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ 22: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ 23: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ 24: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ 25: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ 26: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ 27: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ 28: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ 29: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ 30: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Jinja2-2.1.1/AUTHORS:
+
+ 1: Jinja is written and maintained by Armin Ronacher .
+ 2:
+ 3: Other contributors (as mentionend in :copyright:s) are:
+ 4:
+ 5: - Armin Ronacher
+ 6: - Georg Brandl
+ 7: - Lawrence Journal-World.
+ 8: - Bryan McLemore
+ 9: - Mickaël Guérin
+ 10: - Cameron Knight
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/license-lxml-2.2.2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/license-lxml-2.2.2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,119 @@
+
+ 1: Copyright (c) 2004 Infrae. All rights reserved.
+ 2:
+ 3: Redistribution and use in source and binary forms, with or without
+ 4: modification, are permitted provided that the following conditions are
+ 5: met:
+ 6:
+ 7: 1. Redistributions of source code must retain the above copyright
+ 8: notice, this list of conditions and the following disclaimer.
+ 9:
+ 10: 2. Redistributions in binary form must reproduce the above copyright
+ 11: notice, this list of conditions and the following disclaimer in
+ 12: the documentation and/or other materials provided with the
+ 13: distribution.
+ 14:
+ 15: 3. Neither the name of Infrae nor the names of its contributors may
+ 16: be used to endorse or promote products derived from this software
+ 17: without specific prior written permission.
+ 18:
+ 19: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ 20: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ 21: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ 22: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR
+ 23: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ 24: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ 25: PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ 26: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ 27: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ 28: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ 29: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+----
+
+ 1: Zope Public License (ZPL) Version 2.0
+ 2: -----------------------------------------------
+ 3:
+ 4: This software is Copyright (c) Zope Corporation (tm) and
+ 5: Contributors. All rights reserved.
+ 6:
+ 7: This license has been certified as open source. It has also
+ 8: been designated as GPL compatible by the Free Software
+ 9: Foundation (FSF).
+ 10:
+ 11: Redistribution and use in source and binary forms, with or
+ 12: without modification, are permitted provided that the
+ 13: following conditions are met:
+ 14:
+ 15: 1. Redistributions in source code must retain the above
+ 16: copyright notice, this list of conditions, and the following
+ 17: disclaimer.
+ 18:
+ 19: 2. Redistributions in binary form must reproduce the above
+ 20: copyright notice, this list of conditions, and the following
+ 21: disclaimer in the documentation and/or other materials
+ 22: provided with the distribution.
+ 23:
+ 24: 3. The name Zope Corporation (tm) must not be used to
+ 25: endorse or promote products derived from this software
+ 26: without prior written permission from Zope Corporation.
+ 27:
+ 28: 4. The right to distribute this software or to use it for
+ 29: any purpose does not give you the right to use Servicemarks
+ 30: (sm) or Trademarks (tm) of Zope Corporation. Use of them is
+ 31: covered in a separate agreement (see
+ 32: http://www.zope.com/Marks).
+ 33:
+ 34: 5. If any files are modified, you must cause the modified
+ 35: files to carry prominent notices stating that you changed
+ 36: the files and the date of any change.
+ 37:
+ 38: Disclaimer
+ 39:
+ 40: THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS''
+ 41: AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ 42: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ 43: AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ 44: NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE
+ 45: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ 46: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ 47: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ 48: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ 49: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ 50: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ 51: OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ 52: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ 53: DAMAGE.
+ 54:
+ 55:
+ 56: This software consists of contributions made by Zope
+ 57: Corporation and many individuals on behalf of Zope
+ 58: Corporation. Specific attributions are listed in the
+ 59: accompanying credits file.
+
+----
+
+Copyright (c) 1999-2003 by Secret Labs AB
+ 4: Copyright (c) 1999-2003 by Fredrik Lundh
+ 5:
+ 6: By obtaining, using, and/or copying this software and/or its
+ 7: associated documentation, you agree that you have read, understood,
+ 8: and will comply with the following terms and conditions:
+ 9:
+ 10: Permission to use, copy, modify, and distribute this software and its
+ 11: associated documentation for any purpose and without fee is hereby
+ 12: granted, provided that the above copyright notice appears in all
+ 13: copies, and that both that copyright notice and this permission notice
+ 14: appear in supporting documentation, and that the name of Secret Labs
+ 15: AB or the author not be used in advertising or publicity pertaining to
+ 16: distribution of the software without specific, written prior
+ 17: permission.
+ 18:
+ 19: SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ 20: THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ 21: FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
+ 22: ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ 23: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ 24: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ 25: OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/license-setuptools-0.6c9.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/license-setuptools-0.6c9.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,326 @@
+ 1: Zope Public License (ZPL) Version 2.1
+ 2: -------------------------------------
+ 3:
+ 4: A copyright notice accompanies this license document that
+ 5: identifies the copyright holders.
+ 6:
+ 7: This license has been certified as open source. It has also
+ 8: been designated as GPL compatible by the Free Software
+ 9: Foundation (FSF).
+ 10:
+ 11: Redistribution and use in source and binary forms, with or
+ 12: without modification, are permitted provided that the
+ 13: following conditions are met:
+ 14:
+ 15: 1. Redistributions in source code must retain the
+ 16: accompanying copyright notice, this list of conditions,
+ 17: and the following disclaimer.
+ 18:
+ 19: 2. Redistributions in binary form must reproduce the accompanying
+ 20: copyright notice, this list of conditions, and the
+ 21: following disclaimer in the documentation and/or other
+ 22: materials provided with the distribution.
+ 23:
+ 24: 3. Names of the copyright holders must not be used to
+ 25: endorse or promote products derived from this software
+ 26: without prior written permission from the copyright
+ 27: holders.
+ 28:
+ 29: 4. The right to distribute this software or to use it for
+ 30: any purpose does not give you the right to use
+ 31: Servicemarks (sm) or Trademarks (tm) of the copyright
+ 32: holders. Use of them is covered by separate agreement
+ 33: with the copyright holders.
+ 34:
+ 35: 5. If any files are modified, you must cause the modified
+ 36: files to carry prominent notices stating that you changed
+ 37: the files and the date of any change.
+ 38:
+ 39: Disclaimer
+ 40:
+ 41: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
+ 42: AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ 43: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ 44: AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ 45: NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+ 46: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ 47: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ 48: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ 49: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ 50: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ 51: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ 52: OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ 53: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ 54: DAMAGE.
+
+----
+
+Python 2.4 license
+
+This is the official license for the Python 2.4 release:
+
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC. Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team. In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com). In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property. Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition). Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+ Release Derived Year Owner GPL-
+ from compatible? (1)
+
+ 0.9.0 thru 1.2 1991-1995 CWI yes
+ 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
+ 1.6 1.5.2 2000 CNRI no
+ 2.0 1.6 2000 BeOpen.com no
+ 1.6.1 1.6 2001 CNRI yes (2)
+ 2.1 2.0+1.6.1 2001 PSF no
+ 2.0.1 2.0+1.6.1 2001 PSF yes
+ 2.1.1 2.1+2.0.1 2001 PSF yes
+ 2.2 2.1.1 2001 PSF yes
+ 2.1.2 2.1.1 2002 PSF yes
+ 2.1.3 2.1.2 2002 PSF yes
+ 2.2.1 2.2 2002 PSF yes
+ 2.2.2 2.2.1 2002 PSF yes
+ 2.2.3 2.2.2 2003 PSF yes
+ 2.3 2.2.2 2002-2003 PSF yes
+ 2.3.1 2.3 2002-2003 PSF yes
+ 2.3.2 2.3.1 2002-2003 PSF yes
+ 2.3.3 2.3.2 2002-2003 PSF yes
+ 2.3.4 2.3.3 2004 PSF yes
+ 2.4 2.3 2004 PSF yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+ the GPL. All Python licenses, unlike the GPL, let you distribute
+ a modified version without making your changes open source. The
+ GPL-compatible licenses make it possible to combine Python with
+ other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+ because its license has a choice of law clause. According to
+ CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+ is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PSF LICENSE AGREEMENT FOR PYTHON 2.4
+------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using Python 2.4 software in source or binary form and its
+associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 2.4
+alone or in any derivative version, provided, however, that PSF's
+License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+2001, 2002, 2003, 2004 Python Software Foundation; All Rights Reserved"
+are retained in Python 2.4 alone or in any derivative version prepared
+by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 2.4 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 2.4.
+
+4. PSF is making Python 2.4 available to Licensee on an "AS IS"
+basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.4 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+2.4 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.4,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee. This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python 2.4, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions. Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee. This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party. As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee. Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement. This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013. This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee. This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+ ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands. All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/license-simplejson-2.0.9.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/license-simplejson-2.0.9.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+Copyright (c) 2006 Bob Ippolito
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/commandml-plugin/commandml.jpg
Binary file configurationengine/doc/plugins/commandml-plugin/commandml.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/commandml-plugin/commandml.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/commandml-plugin/commandml.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,270 @@
+User guide for Command Plugin
+-----------------------------
+
+Introduction
+'''''''''''''
+This page describes how to use ConE command plugin. Command plugin is a ConE plugin,
+which purpose is to run external tools and scripts to generate files to target image.
+Command plugin is configured in CommandML files that describes tools that are run
+and options that are used.
+
+CommandML files are executed by default in **normal** :ref:`invocation phase `.
+
+CommandML
+'''''''''
+
+The CommandML syntax is a extension of Configuration markup language (confml). The term in confml for this extension
+is implementation method language (implml), which in CommandML case is a xml file.
+
+All input values can be given as ConfML refs or as plain text. Also mixing text and ConfML ref information
+is supported.
+
+ * Namespace: ``http://www.s60.com/xml/commandml/1``
+ * File extension: ``commandml``
+
+.. note::
+
+ More information about :ref:`file extensions `.
+
+CommandML Elements
+..................
+
+The CommandML model is drawn out as a uml model in below picture.
+
+ .. image:: commandml.jpg
+
+.. note::
+
+ CommandML supports also common ImplML elements. More information about :ref:`ImplML elements `.
+
+ Element
+**************************
+
+The ``commandml`` element is the root element of the configuration, and acts as a container to the rest of the elements.
+
+Child Elements
+++++++++++++++++++++++++++
+
+==================== ====================== ===============================================================================
+Element Cardinality Description
+==================== ====================== ===============================================================================
+condition 0 .. * Defines a group of commands that are run only if command is evaluated as True.
+command 0 .. * Defines properties for one executable.
+==================== ====================== ===============================================================================
+
+Example
+++++++++++++++++++++++++++
+
+.. code-block:: xml
+
+
+
+ Element
+**************************
+
+``Condition`` element defines a group of commands that are run only if command is evaluated as True.
+
+
+Child Elements
+++++++++++++++++++++++++++
+
+Condition can contain arbitrary number of commands and they are run in definition order so that next command is executed
+only after the previous has ended.
+
+==================== ====================== ===============================================================================
+Element Cardinality Description
+==================== ====================== ===============================================================================
+command 0 .. * Defines properties for one executable.
+==================== ====================== ===============================================================================
+
+Attributes
+++++++++++++++++++++++++++
+
+Condition has only one attribute ``value`` which can contains any Python code and ConfML refs. Refs are first expanded
+and then the value is evaluated using Python eval function.
+
+==================== ====================== ===============================================================================
+Attribute Required Description
+==================== ====================== ===============================================================================
+value Yes Defines a condition value that can contain any Python code and ConfML refs.
+==================== ====================== ===============================================================================
+
+Example
+++++++++++++++++++++++++++
+
+.. code-block:: xml
+
+
+
+
+
+This will run notepad.exe only if value in ConfML ref ``runconfig.notepad`` is not empty.
+
+ Element
+**************************
+
+``Command`` element defines properties for one executable. Basically it provides same features that Python subprocess
+module. Commands can be defined either inside condition elements and directly under ``commandml``. Running order of
+commands is the same that is defined in commandml file. Definition of those can be found from
+`Python subprocess documentation `_.
+
+Child Elements
+++++++++++++++++++++++++++
+
+Command element can have arguments, pipes and filters as sub-elements.
+
+==================== ====================== ===============================================================================
+Element Cardinality Description
+==================== ====================== ===============================================================================
+argument 0 .. * Defines argument for executable.
+pipe 0 .. * Defines pipe for executable.
+filter 0 .. * Defines filter for executable.
+==================== ====================== ===============================================================================
+
+
+Attributes
+++++++++++++++++++++++++++
+
+Command element has one mandatory argument ``executable`` and four optional attributes: ``shell``, ``env``, ``cwd``, ``bufsize``.
+
+==================== ====================== ===============================================================================
+Attribute Required Description
+==================== ====================== ===============================================================================
+executable Yes Defines a program to execute. Value can contain any Python code and ConfML refs.
+shell No Defines is the specified command executed through the shell.
+env No Defines the environment variables for the new process.
+cwd No Defines the current directory that will be changed to cwd before command is
+ executed. Note that this directory is not considered when searching the
+ executable, so you can't specify the program's path relative to cwd.
+bufsize No Defines the pipe buffering: 0 means unbuffered, 1 means line buffered,
+ any other positive value means use a buffer of (approximately) that size.
+ A negative bufsize means to use the system default, which usually means
+ fully buffered. The default value for bufsize is 0 (unbuffered).
+==================== ====================== ===============================================================================
+
+Example
+++++++++++++++++++++++++++
+
+.. code-block:: xml
+
+
+
+
+
+ Element
+**************************
+
+``Argument`` element defines one command line argument for it's parent command.
+
+
+Attributes
+++++++++++++++++++++++++++
+
+Value is given in attribute ``value`` and can contain any string value. When executing the command all attributes are
+combined to be a single string that is passed as a parameter to executable.
+
+==================== ====================== ===============================================================================
+Attribute Required Description
+==================== ====================== ===============================================================================
+value Yes Defines a one command line argument for it's parent command.
+==================== ====================== ===============================================================================
+
+Example
+++++++++++++++++++++++++++
+
+.. code-block:: xml
+
+
+
+
+
+ Element
+**************************
+
+Pipes are used to specify executed program's standard input, output and error file handles.
+
+Attributes
+++++++++++++++++++++++++++
+
+``Pipe`` has two mandatory arguments ``name`` and ``value``.
+
+==================== ====================== ===============================================================================
+Attribute Required Description
+==================== ====================== ===============================================================================
+name Yes Defines the name of the pipe. Possible values are: "stdin", "stdout" and
+ "stderr". That are executed programs' standard input, standard output and
+ standard error file handles, respectively.
+value Yes Value can be either PIPE to indicate that new should be defined or then
+ filename. Stderr additionally can have also value STDOUT, which indicates that
+ the stderr data from the applications should be captured into the same file
+ handle as for stdout.
+==================== ====================== ===============================================================================
+
+Example
+++++++++++++++++++++++++++
+
+.. code-block:: xml
+
+
+
+
+ Element
+**************************
+
+Filters are used to analyse output of executed command and report the findings to ConE log file. This enables that
+executed program's errors are easily available for users.
+
+Attributes
+++++++++++++++++++++++++++
+
+``Filter`` element has four attributes: ``severity``, ``condition``, ``input`` and ``formatter``.
+
+==================== ====================== ===============================================================================
+Attribute Required Description
+==================== ====================== ===============================================================================
+severity Yes Defines logging level e.g. "info" means that possible findings are reported as
+ info elements. Other options for severity are "warning", "debug", "exception",
+ "error" and "critical". Default value is "info".
+condition Yes Defines a Python regexp pattern that is used to match lines from the
+ defined input pipe. Notice that you can use named groups to get some relevant
+ information stored for formatter use.
+input Yes Input can be either "stdout" or "stderr".
+formatter No Formatter defines how the findings are reported in ConE output. It is
+ sprintf-style string which can contain named groups from condition. If
+ formatter is empty found line is printed as such. See examples below.
+==================== ====================== ===============================================================================
+
+Example
+++++++++++++++++++++++++++
+
+.. code-block:: xml
+
+
+
+
+
+The first one defines that findings are reported as info elements. Condition element defines two named groups "name" and
+"uid" which are also used in formatter when printing information to ConE's log file.
+The second one tries to find any line containing word "successfully" and prints the whole line as debug element.
+The last one print all failed cases as errors and uses again named groups to extract data from input stream.
+
+
+Full example files
+''''''''''''''''''
+
+.. literalinclude:: preinstall.commandml
+ :language: xml
+
+
+XSD
+'''
+
+.. note::
+
+ This will be added later.
+
+
+FAQ
+'''''''''''''
+
+This will be updated based on the questions.
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/commandml-plugin/preinstall.commandml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/commandml-plugin/preinstall.commandml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/contentml-plugin/content.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/contentml-plugin/content.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,168 @@
+How to use the ConE Content plugin
+==================================
+
+Introduction
+'''''''''''''
+The basic concept of Content plugin is to transfer file resources from
+one place to another. So one may have for example; an audio file stored in the
+configuration project and needs to define the audio file location in the
+device. With ConE Content plugin you can basically define a copy operation.
+You just create .content (or general *.implml file) type file to the configuration project implml folder
+and set the rules or filters in there.
+
+
+content elements
+----------------
+The content model is drawn out as a uml model in below picture.
+
+ .. image:: content2.jpg
+
+content
+^^^^^^^
+The root element of the content file is always content, which defines the xml namespace (xmlns)
+to http://www.s60.com/xml/content/2 in the current version.
+
+**content example**::
+
+
+
+tag
+^^^^
+
+Implementation tag elements can be defined under the root element. See the page on `tags `_ for more info.
+
+output
+^^^^^^
+The output element can define a output folder where content is copied from :ref:`content-input` elements that
+are children of this particular output. There can be several output elements inside a single content
+file or block.
+
+**output example**::
+
+
+
+The above statement defines that content is copied under foobar folder in the cone output folder.
+
+
+.. _content-input:
+
+input
+^^^^^^
+The user can define input under the output element. The input element can define a source directory and two file filters for
+that directory (include and exclude filters). The input element will always search files under the content directories of the
+configuration project. But the content of the search directory is a layered content of all configuration project content directories
+(See content layering in Configuration project specification (TODO: add link here)).
+
+**input example**::
+
+
+
+the above statement would include all files found under foobar directory.::
+
+
+
+the above statement would include file1.txt from folder foobar to the copy operation.
+
+include
+^^^^^^^^
+The include filter can be used inside input statement to filter files for the copy operation.
+
+The include filter can have following attributes.
+
++------------------+-------------------------------------------+
+| Attribute name | description |
++==================+===========================================+
+| files | comma separated list of inpu files. |
++------------------+-------------------------------------------+
+| pattern | regexp pattern to filter input files that |
+| | are found in the input folder. |
++------------------+-------------------------------------------+
+| flatten | "true"|"false" to define if the directory |
+| | struture is flattened at output. |
++------------------+-------------------------------------------+
+
+**input include example**
+
+This would copy files foobar/test/override.txt and foobar/test/s60.txt to output if they are found.::
+
+
+
+
+
+The below statement would copy all files ending with ".jpg" from userdata and copy them
+directly to the output root folder.::
+
+
+
+
+
+exclude
+^^^^^^^^
+The exclude filter can be used similarly as the include filter, but in a negative meaning.
+For example to ensure that files beginning with a dot are never copied.
+
+The exclude filter can have following attributes.
+
++------------------+-------------------------------------------+
+| Attribute name | description |
++==================+===========================================+
+| pattern | regexp pattern to filter input files that |
+| | are found in the input folder. |
++------------------+-------------------------------------------+
+
+**input exclude example**
+
+This would exclude all files that have .svn as part of the file path::
+
+
+
+
+
+
+How to create a content file
+----------------------------
+
+* Create a new file in the content folder name for ex. mycontentfile.content
+* Set the file encoding to UTF-8
+* Set the definition tag first **
+* Set the content tag **
+* Set the description tag *Copy only prod *
+* Set a content configuration tag for ex. * *
+* Set another content configuration tag for ex. * *
+* Close the content tag * *
+
+Now you have content file which copies the prod files to the content directory in the device configuration
+
+**example of a entire content file**
+
+The example defines here two copy operations to two different outputs. First one to content with selected
+files as input and the other to include, where it tries to copy all \*.hrh files to the root of the include
+directory.
+
+.. literalinclude:: example.content
+
+
+Logic and rules
+---------------
+
+What may you define with content file logic. Here are some explanations.
+
+* * * include the files in the prod folder
+* * * exclude the files in the prod folder
+* * * input files are setted in the value of the content/inputdir reference link in confml
+* * * output files are setted in the value of the content/outputdir reference link in confml
+
+So you may include and exclude folder and files. Content file definition supports regex patterns
+You may give the location of the content as a confml reference link, *note: use the dots instead of slashes*
+
+
+XSD
+---
+
+.. literalinclude:: ../../xsd/contentml2.xsd
+ :linenos:
+
+
+FAQ
+---
+This will be updated based on the questions.
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/contentml-plugin/content2.jpg
Binary file configurationengine/doc/plugins/contentml-plugin/content2.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/contentml-plugin/content_model.bmp
Binary file configurationengine/doc/plugins/contentml-plugin/content_model.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/contentml-plugin/example.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/contentml-plugin/example.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/convertprojectplugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/convertprojectplugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,119 @@
+User guide for Convert Project Plugin
+-------------------------------------
+
+Introduction
+'''''''''''''
+This page describes how to use and configure Convert Project plugin. This plugin is
+used to convert old style configuration structure to Configuration project. The plugin
+can be used to create files and folders. For a folder you can define using absolute paths
+or wildcards which files from previous structure are copied to the new structure. For files
+it is possible just to copy a file from one location to another, create layer and configuration
+root files. For these more complex type of files you can select which files are included using
+absolute path or wildcards.
+
+
+Configuring
+''''''''''''
+Plugin is configured by modifying .convertprojectml file that must be located in some layer's implml folder
+that is included in generated configuration. Typical case is that the plugin is used in products that don't
+have configuration project and layers. In that case refer to Installation/Running part.
+
+Convert Project ML format
+~~~~~~~~~~~~~~~~~~~~~~~~~~
++------------------+-----------------+----------------+-------------------------------+
+| Elements | Attributes | Content model | Description |
++==================+=================+================+===============================+
+| convertprojectml | xmlns |targetProject | Collective/Top-most element |
+| | |layer* | defines the namespace used |
+| | |foreach* | in the file. |
++------------------+-----------------+----------------+-------------------------------+
+| targetProject | path | | Defines output path. By the |
+| | validate | | default all the paths later |
+| | | | are relative to this path. |
++------------------+-----------------+----------------+-------------------------------+
+| layer | path | folder* | Defines one configuration |
+| | | file* | layer. Creates new layer |
+| | | | folder defined in the path. |
+| | | | Folder and file paths are |
+| | | | relative to this path. |
++------------------+-----------------+----------------+-------------------------------+
+| folder | path | filter* | Defines one folder inside a |
+| | | | layer. Creates new folder |
+| | | | using path. Filter paths are |
+| | | | relative to this path. |
++------------------+-----------------+----------------+-------------------------------+
+| file | path | filter* | Element which can be used |
+| | type | | for three different purposes. |
+| | | | Copying files, creating layer |
+| | | | roots and configuration roots.|
+| | | | Path defines target filename |
+| | | | and type which kind of file |
+| | | | is created. |
++------------------+-----------------+----------------+-------------------------------+
+| filter | action | | Filter is the element that |
+| | data | | does all the work. It has |
+| | remove_includes | | attribute action, which can be|
+| | | | add, remove, include_file or |
+| | | | include_layer. Data defines |
+| | | | the search pattern for action |
+| | | | Remove_includes can be used to|
+| | | | remove all existing includes |
+| | | | from files that are included |
+| | | | in layer root file. |
++------------------+-----------------+----------------+-------------------------------+
+
+
+Installation/Running
+'''''''''''''''''''''
+1. Download and install ConE according the ConE installation documentation.
+2. Go to \\epoc32\\rom\\config folder
+3. Create convertproject and convertproject\\implml folders
+4. Copy example create_project.convertprojectml to convertproject\\implml folder
+5. Modify according your needs
+6. Create a layer root file called root.confml in convertproject folder. Use the following content:
+
+.. code-block:: xml
+
+
+
+
+
+7. Create configuration root file called convert.confml in \epoc32\rom\config folder. Use the following content:
+
+.. code-block:: xml
+
+
+
+
+
+
+8. Run ConE to generate content.
+
+::
+
+ \epoc32\rom\config>cone --action generate -c convert.confml
+
+
+Examples
+'''''''''
+
+XSD
+'''
+
+Download: :download:`projectml.xsd `
+
+
+FAQ
+'''''''''
+This will be updated based on the questions.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/crml-plugin/crml.jpg
Binary file configurationengine/doc/plugins/crml-plugin/crml.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/crml-plugin/crmlplugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/crml-plugin/crmlplugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,203 @@
+User guide for Crml Plugin usage in ConE
+----------------------------------------
+
+Introduction
+'''''''''''''
+This page describes how to use ConE crml plugin. Crml plugin generates cenrep files out of
+configuration project which contains valid confml files and matching crml files.
+Generated files can be included in phone image and creates settings according to confml and crml files.
+You may change confml values and generate or regenerate confml project and thge generated cenrep files are changed
+to given values. All files will be file encoded to UTF-16, (so you need a UTF-16 supported editor to view the
+contents of the files)
+
+CrML files are executed by default in **normal** :ref:`invocation phase `.
+
+CrML
+'''''''''
+
+The CrML syntax is a extension of Configuration markup language (confml). The term in confml for this extension
+is implementation method language (implml), which in CrML case is a xml file.
+
+All input values can be given as ConfML refs or as plain text. Also mixing text and ConfML ref information
+is supported.
+
+ * Namespace: ``http://www.s60.com/xml/cenrep/1``
+ * File extension: ``crml``
+
+.. note::
+
+ More information about :ref:`file extensions `.
+
+CrML Elements
+.............
+
+The CrML model is drawn out as a uml model in below picture.
+
+ .. image:: crml.jpg
+
+.. note::
+
+ CrML supports also common ImplML elements. More information about :ref:`ImplML elements ` .
+
+
+ Element
+**************************
+
+The repository element represents a single key repository (keyspace) in Central Repository.
+
+Child Elements
+++++++++++++++
+
+==================== ====================== ===============================================================================
+Element Cardinality Description
+==================== ====================== ===============================================================================
+key 0 .. * Defines a single key in repository in Central Repository.
+keyRange 0 .. * Defines a range of keys in repository in Central Repository.
+access 0 .. 2 Defines a represents read or write access control policy for a single key
+ or a key range.
+==================== ====================== ===============================================================================
+
+Attributes
+++++++++++
+
+=================================== ====================== ===============================================================================
+Attribute Required Description
+=================================== ====================== ===============================================================================
+version Yes Defines the version of the language used. Must have value "1.0".
+uidName Defines the unique identifier of the repository in symbolic form.
+uidValue Defines the unique identifier of the repository in hexadecimal form.
+initialialisationFileVersion Defines the version of the initialization file format. Default value is "1".
+owner Defines the SID of the application or component which is responsible for
+ backing up the repository. Defined in the form of hexadecimal number.
+ Mandatory in case if repository contents are to be backed up by the secure
+ backup server.
+backup Defines the default backup policy for runtime created keys. The supported
+ values are "true" and "false". Should be set to true for non-read-only
+ (that is, runtime writable) keys only. Default value is false.
+=================================== ====================== ===============================================================================
+
+
+Example
++++++++
+
+.. code-block:: xml
+
+
+ Keys for Avkon
+
+ ...
+
+ First version
+
+ ...
+
+
+ ...
+
+
+ ...
+
+
+
+
+ Element
+**************************
+
+The key element represents a single key in repository in Central Repository.
+
+Child Elements
+++++++++++++++
+
+==================== ====================== ===============================================================================
+Element Cardinality Description
+==================== ====================== ===============================================================================
+value 0 .. * Defines a mapping from a logical value in Configuration ML to an implementation
+ specific value in a key in Central Repository.
+bit 0 .. * Defines a mapping from values of set of Boolean type settings in Configuration
+ ML to a bitmask stored in a single key in Central Repository..
+access 0 .. 2 Defines a represents read or write access control policy for a single key
+ or a key range.
+==================== ====================== ===============================================================================
+
+Attributes
+++++++++++
+
+=================================== ====================== ===============================================================================
+Attribute Required Description
+=================================== ====================== ===============================================================================
+name Yes Defines the version of the language used. Must have value "1.0".
+=================================== ====================== ===============================================================================
+
+
+Example
++++++++
+
+.. code-block:: xml
+
+
+ Keys for Avkon
+
+ ...
+
+ First version
+
+ ...
+
+
+ ...
+
+
+ ...
+
+
+
+
+
+
+
+
+
+
+
+
+
+Examples
+'''''''''
+
+**Cenrep file example**
+
+* cenrep
+* version 1
+* [defaultmeta]
+* 0
+* cap_rd=alwayspass cap_wr=alwayspass
+* [Main]
+* 0x1 int 21 0 cap_rd=alwayspass cap_wr=alwaysfail
+* 0x3 int 1801115478 0 cap_wr=alwaysfail
+* 0x4 int 1082261569 0 cap_wr=alwaysfail
+
+**What do the values mean**
+
+
+* cenrep = tells that this is a cenrep configuration
+* version = current version value
+* [defaultmeta] = if the value is zero this file is not backuped in the rofs
+* [platsec] = the values tells that which capabilities are passed or failed
+* [Main] = start of the cenrep value information
+* ex. 0x4 int 1082261569 0 cap_wr=alwaysfail
+* eq. key key type value backup value capabilities
+
+XSD
+'''''''''
+
+Download: :download:`crml.xsd `
+
+
+FAQ
+'''''''''
+This will be updated based on the questions.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/diagrams.uml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/diagrams.uml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1801 @@
+
+
+
+
+
+
+
+
+
+
+Untitled
+1
+
+Model1
+6KeNJgr/wES9F4tJ3lK8RAAA
+1
+
+plugin_classes
+NmvwO09X4Uu7xy6qNwdIDQAA
+
+xjfMh7hHB0yRVVZEtg/P0gAA
+32
+
+clMaroon
+$00B9FFFF
+108
+68
+693
+285
+Hwg8xLPVZkC6P9CDdGGF+AAA
+
+
+ConE
+
+
+False
+
+
+False
+
+
+
+
+clMaroon
+$00B9FFFF
+440
+380
+377
+117
+4cKvVc5Dtk6rtkH3X3B9egAA
+
+
+SomePlugin
+
+
+False
+
+
+False
+
+
+
+
+clMaroon
+$00B9FFFF
+140
+148
+102
+91
+q11CD3et4kixnDRLW4nPdgAA
+
+
+1
+ImplContainer
+
+
+False
+
+
+False
+
+
+
+q11CD3et4kixnDRLW4nPdgAA
+
+
+q11CD3et4kixnDRLW4nPdgAA
+
+
+False
+q11CD3et4kixnDRLW4nPdgAA
+
+
+
+clMaroon
+$00B9FFFF
+468
+128
+102
+137
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+3
+ImplBase
+
+
+False
+
+
+False
+
+
+
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+False
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+
+clMaroon
+$00B9FFFF
+704
+152
+78
+56
+lPra4OiszU2H/arMBBwTVgAA
+
+
+3
+ReaderBase
+
+
+False
+
+
+False
+
+
+
+lPra4OiszU2H/arMBBwTVgAA
+
+
+lPra4OiszU2H/arMBBwTVgAA
+
+
+False
+lPra4OiszU2H/arMBBwTVgAA
+
+
+
+clMaroon
+$00B9FFFF
+248
+264
+132
+69
+3dlH2vm6sEayyvEaXZoCngAA
+
+
+1
+ImplFactory
+
+
+False
+
+
+False
+
+
+
+3dlH2vm6sEayyvEaXZoCngAA
+
+
+3dlH2vm6sEayyvEaXZoCngAA
+
+
+False
+3dlH2vm6sEayyvEaXZoCngAA
+
+
+
+clMaroon
+$00DFFFFF
+468
+516
+207
+38
+The reader parses an ElementTree into
+an implementation instance
+
+
+
+clMaroon
+$00B9FFFF
+684
+412
+109
+43
+rDKOyCdZEkCOx+oFSF1RfgAA
+
+
+1
+SomeImplReader
+
+
+False
+
+
+False
+
+
+
+rDKOyCdZEkCOx+oFSF1RfgAA
+
+
+rDKOyCdZEkCOx+oFSF1RfgAA
+
+
+False
+rDKOyCdZEkCOx+oFSF1RfgAA
+
+
+
+clMaroon
+$00B9FFFF
+488
+412
+80
+43
+JQvuxGbsdE2jFadShkxqKgAA
+
+
+1
+SomeImpl
+
+
+False
+
+
+False
+
+
+
+JQvuxGbsdE2jFadShkxqKgAA
+
+
+JQvuxGbsdE2jFadShkxqKgAA
+
+
+False
+JQvuxGbsdE2jFadShkxqKgAA
+
+
+
+clMaroon
+$00B9FFFF
+526,412;521,264
+0MZJX1cCj0mQ/11HQ5cN7AAA
+KeRNcoIQK0KSH6AGF9UzjAAA
+3rR9ifA3E0iINKcyT2xupAAA
+
+False
+1.5707963267949
+15
+0MZJX1cCj0mQ/11HQ5cN7AAA
+
+
+False
+1.5707963267949
+30
+0MZJX1cCj0mQ/11HQ5cN7AAA
+
+
+False
+-1.5707963267949
+15
+0MZJX1cCj0mQ/11HQ5cN7AAA
+
+
+
+clMaroon
+$00B9FFFF
+738,412;742,207
+mo5tewceOUm0VDnSWRFvzgAA
+2t2cUMI4f0SGZ3fMzCfV2QAA
+4SjQyNgUikC1rO8p+sfTWgAA
+
+False
+1.5707963267949
+15
+mo5tewceOUm0VDnSWRFvzgAA
+
+
+False
+1.5707963267949
+30
+mo5tewceOUm0VDnSWRFvzgAA
+
+
+False
+-1.5707963267949
+15
+mo5tewceOUm0VDnSWRFvzgAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+468,193;241,193
+zHN3b0KW5kCvSqS/RtHanwAA
+EFzcsknNQ0O+rr8VseO9MAAA
+KeRNcoIQK0KSH6AGF9UzjAAA
+
+False
+1.5707963267949
+15
+zHN3b0KW5kCvSqS/RtHanwAA
+
+
+False
+1.5707963267949
+30
+zHN3b0KW5kCvSqS/RtHanwAA
+
+
+False
+-1.5707963267949
+15
+zHN3b0KW5kCvSqS/RtHanwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+YdiI7jGOKUSsfpXfOQgATwAA
+
+
+False
+0.523598775598299
+30
+epTail
+28/H60miw0SOAfSjEXfz2wAA
+
+
+False
+0.523598775598299
+25
+epHead
+YdiI7jGOKUSsfpXfOQgATwAA
+
+
+False
+-0.523598775598299
+25
+epTail
+28/H60miw0SOAfSjEXfz2wAA
+
+
+False
+-0.785398163397448
+40
+epHead
+YdiI7jGOKUSsfpXfOQgATwAA
+
+
+False
+0.785398163397448
+40
+epTail
+28/H60miw0SOAfSjEXfz2wAA
+
+
+False
+-992
+-884
+50
+8
+YdiI7jGOKUSsfpXfOQgATwAA
+
+
+False
+-992
+-884
+50
+8
+28/H60miw0SOAfSjEXfz2wAA
+
+
+
+clMaroon
+$00DFFFFF
+264
+178
+53
+ImplContainer contains a number
+of implementation instances and
+generates output using them.
+
+
+
+clMaroon
+$00B9FFFF
+354,193;352,52
+TDaVJ50TjUeD2ieOY0LepAAA
+qO84lDa9Q0qJdFLxAzRcQQAA
+
+
+clMaroon
+$00B9FFFF
+684,433;567,433
+FJ1X3D9c80uG5EgY7ATqzQAA
+3rR9ifA3E0iINKcyT2xupAAA
+4SjQyNgUikC1rO8p+sfTWgAA
+
+-1.48013734123357
+11.0453610171873
+creates
+FJ1X3D9c80uG5EgY7ATqzQAA
+
+
+False
+1.5707963267949
+30
+FJ1X3D9c80uG5EgY7ATqzQAA
+
+
+False
+-1.5707963267949
+15
+FJ1X3D9c80uG5EgY7ATqzQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+XFmHn8b6Sk2ycMUt8wH3vAAA
+
+
+False
+0.523598775598299
+30
+epTail
+eu5J5ZGSGUmZFfbh0cHFewAA
+
+
+False
+0.523598775598299
+25
+epHead
+XFmHn8b6Sk2ycMUt8wH3vAAA
+
+
+False
+-0.523598775598299
+25
+epTail
+eu5J5ZGSGUmZFfbh0cHFewAA
+
+
+False
+-0.785398163397448
+40
+epHead
+XFmHn8b6Sk2ycMUt8wH3vAAA
+
+
+False
+0.785398163397448
+40
+epTail
+eu5J5ZGSGUmZFfbh0cHFewAA
+
+
+False
+-988
+-828
+50
+8
+XFmHn8b6Sk2ycMUt8wH3vAAA
+
+
+False
+-988
+-828
+50
+8
+eu5J5ZGSGUmZFfbh0cHFewAA
+
+
+
+clMaroon
+$00B9FFFF
+625,433;581,516
+rgxZZaZClU6wEpDN1SC00gAA
+iyKZKLbxiESYfeiNMEfWLgAA
+
+
+clMaroon
+$00DFFFFF
+56
+384
+202
+83
+When an ImplContainer is created
+on a Configuration,
+ImplFactory.get_impls_from_file()
+is used on all supported files to create
+the list of implementation instances.
+
+
+
+clMaroon
+$00B9FFFF
+207,384;271,332
+zI4lKX8LzEOx0+WhlofgbAAA
+WEQcc/1ot022Zyx0YQRFvgAA
+
+
+clMaroon
+$00B9FFFF
+183,238;162,384
+WEQcc/1ot022Zyx0YQRFvgAA
+EFzcsknNQ0O+rr8VseO9MAAA
+
+
+clMaroon
+$00DFFFFF
+200
+496
+192
+68
+ImplContainer.get_impls_from_file()
+in turn uses all registered reader
+classes to create the actual
+implementations.
+
+
+
+clMaroon
+$00B9FFFF
+310,332;298,496
+zA6aIDQK/EuSXUqQ3E5MsQAA
+zI4lKX8LzEOx0+WhlofgbAAA
+
+
+clMaroon
+$00B9FFFF
+488,449;375,496
+zA6aIDQK/EuSXUqQ3E5MsQAA
+3rR9ifA3E0iINKcyT2xupAAA
+
+
+clMaroon
+$00B9FFFF
+684,445;391,508
+zA6aIDQK/EuSXUqQ3E5MsQAA
+4SjQyNgUikC1rO8p+sfTWgAA
+
+
+clMaroon
+$00DFFFFF
+568
+16
+190
+38
+ImplBase and ReaderBase comprise
+the ConE plug-in interface
+
+
+
+clMaroon
+$00B9FFFF
+569,139;645,53
+D2lNkx9zqkGIrORCziB2MwAA
+KeRNcoIQK0KSH6AGF9UzjAAA
+
+
+clMaroon
+$00B9FFFF
+727,152;672,53
+D2lNkx9zqkGIrORCziB2MwAA
+2t2cUMI4f0SGZ3fMzCfV2QAA
+
+
+clMaroon
+$00DFFFFF
+20
+12
+167
+38
+ImplContainer is used when
+generating output using ConE.
+
+
+
+clMaroon
+$00B9FFFF
+166,148;113,49
+v84tCD/ORU6aA+sNvC8HbgAA
+EFzcsknNQ0O+rr8VseO9MAAA
+
+
+clMaroon
+$00B9FFFF
+241,237;273,264
+C72p+KeoXkaRHqlZwhKDHgAA
+zI4lKX8LzEOx0+WhlofgbAAA
+EFzcsknNQ0O+rr8VseO9MAAA
+
+1.5707963267949
+15
+uses
+C72p+KeoXkaRHqlZwhKDHgAA
+
+
+False
+1.5707963267949
+30
+C72p+KeoXkaRHqlZwhKDHgAA
+
+
+False
+-1.5707963267949
+15
+C72p+KeoXkaRHqlZwhKDHgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+DDj3t0783k6mjECBMHSRZgAA
+
+
+False
+0.523598775598299
+30
+epTail
+isxYyJJ+aEilbZtDDhOMqwAA
+
+
+False
+0.523598775598299
+25
+epHead
+DDj3t0783k6mjECBMHSRZgAA
+
+
+False
+-0.523598775598299
+25
+epTail
+isxYyJJ+aEilbZtDDhOMqwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+DDj3t0783k6mjECBMHSRZgAA
+
+
+False
+0.785398163397448
+40
+epTail
+isxYyJJ+aEilbZtDDhOMqwAA
+
+
+False
+-1000
+-1000
+50
+8
+DDj3t0783k6mjECBMHSRZgAA
+
+
+False
+-1000
+-1000
+50
+8
+isxYyJJ+aEilbZtDDhOMqwAA
+
+
+
+clMaroon
+$00B9FFFF
+379,303;688,324;728,412
+zR4RT17TyUGNWLtHCk4EHQAA
+4SjQyNgUikC1rO8p+sfTWgAA
+zI4lKX8LzEOx0+WhlofgbAAA
+
+-2.23603261405275
+76.1577310586391
+uses
+zR4RT17TyUGNWLtHCk4EHQAA
+
+
+False
+1.5707963267949
+30
+zR4RT17TyUGNWLtHCk4EHQAA
+
+
+False
+-1.5707963267949
+15
+zR4RT17TyUGNWLtHCk4EHQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+AeNNCbWnPEKWIb774GWlfQAA
+
+
+False
+0.523598775598299
+30
+epTail
++uses
+3XKRVnprcUe5DKIkXzT8QQAA
+
+
+False
+0.523598775598299
+25
+epHead
+AeNNCbWnPEKWIb774GWlfQAA
+
+
+False
+-0.523598775598299
+25
+epTail
+3XKRVnprcUe5DKIkXzT8QQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+AeNNCbWnPEKWIb774GWlfQAA
+
+
+False
+0.785398163397448
+40
+epTail
+3XKRVnprcUe5DKIkXzT8QQAA
+
+
+False
+-1000
+-1000
+50
+8
+AeNNCbWnPEKWIb774GWlfQAA
+
+
+False
+-1000
+-1000
+50
+8
+3XKRVnprcUe5DKIkXzT8QQAA
+
+
+
+clMaroon
+$00DFFFFF
+700
+540
+163
+53
+SomePlugin provides concrete
+implementations for ImplBase
+and ReaderBase.
+
+
+
+clMaroon
+$00B9FFFF
+697,496;750,540
+gHH7Ol36xE6LN+W/djXgswAA
+xW95yby7XEChYzUI8UtliAAA
+
+
+
+17
+
+ImplContainer
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+EFzcsknNQ0O+rr8VseO9MAAA
+SdderwBH1U26ZhKsIrAmQwAA
+53//Or3SzEObbCGytvM8TQAA
+SQxim4OCp0+ZJfNVeMS4aAAA
+3
+
+list_output_files
+q11CD3et4kixnDRLW4nPdgAA
+
+
+generate
+q11CD3et4kixnDRLW4nPdgAA
+
+
+post_generate
+q11CD3et4kixnDRLW4nPdgAA
+
+2
+YdiI7jGOKUSsfpXfOQgATwAA
+isxYyJJ+aEilbZtDDhOMqwAA
+
+
+GenerationContext
+NmvwO09X4Uu7xy6qNwdIDQAA
+1
+
+tags
+WHtheP8K+EOVIcif9grlKAAA
+
+
+
+ImplBase
+True
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+KeRNcoIQK0KSH6AGF9UzjAAA
+94btHH+JUU+ao60nWTUwWgAA
+kRd6Ga/WzUSYRVtlWUo1fwAA
+qDts8Y2Udkq6d1jGIg7T4wAA
+1
+0MZJX1cCj0mQ/11HQ5cN7AAA
+7
+
+generate
+True
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+post_generate
+True
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+list_output_files
+True
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+get_refs
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+get_tags
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+has_ref
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+
+has_tag
+g0zWWZA9xEWvFh0sRnmMqgAA
+
+1
+28/H60miw0SOAfSjEXfz2wAA
+
+
+ReaderBase
+True
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+2t2cUMI4f0SGZ3fMzCfV2QAA
+/u6i3dXZNU2AP0PCNI7GSQAA
+uNXhwkTmbEquIsikeV1LWAAA
+88ZZOi003UKll1SgqtSxEQAA
+1
+mo5tewceOUm0VDnSWRFvzgAA
+1
+
+read_impl
+True
+lPra4OiszU2H/arMBBwTVgAA
+
+
+
+SomeImpl
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+3rR9ifA3E0iINKcyT2xupAAA
+H66ci42eykeVpww3gwtXTwAA
+irrPzs4H9UeRXWlc31bdZQAA
+syhxMXb3YE2k1uMifcmEVQAA
+1
+0MZJX1cCj0mQ/11HQ5cN7AAA
+1
+XFmHn8b6Sk2ycMUt8wH3vAAA
+
+
+ImplFactory
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+zI4lKX8LzEOx0+WhlofgbAAA
+ddVvnRrsbk6JMbZwvUAIMwAA
+SrKOQ+6xAEixnwjVm44qzwAA
+i49PYXAsJEeL78AfaOuTSwAA
+2
+
+is_supported_impl_file
+3dlH2vm6sEayyvEaXZoCngAA
+
+
+get_impls_from_file
+3dlH2vm6sEayyvEaXZoCngAA
+
+2
+DDj3t0783k6mjECBMHSRZgAA
+3XKRVnprcUe5DKIkXzT8QQAA
+
+
+Configuration
+NmvwO09X4Uu7xy6qNwdIDQAA
+
+
+Jung, Yoontae
+NmvwO09X4Uu7xy6qNwdIDQAA
+
+
+SomeImplReader
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+4SjQyNgUikC1rO8p+sfTWgAA
+85Z9UACcZEOduM93pKK9dwAA
+WpQE1QO6okWgjYYOPj427QAA
+jA/eMkbe1UOQyseQvko2pAAA
+1
+mo5tewceOUm0VDnSWRFvzgAA
+2
+eu5J5ZGSGUmZFfbh0cHFewAA
+AeNNCbWnPEKWIb774GWlfQAA
+
+
+NmvwO09X4Uu7xy6qNwdIDQAA
+JQvuxGbsdE2jFadShkxqKgAA
+g0zWWZA9xEWvFh0sRnmMqgAA
+4
+WkxNO77jO0iqN3Zx3pTsXAAA
+hq+xPUiczUiXV1J9khEpCgAA
+oxtgEPTKIkyuZW+/1ioAPAAA
+C3LeagDb40ac4fqEDvNK5AAA
+
+
+NmvwO09X4Uu7xy6qNwdIDQAA
+rDKOyCdZEkCOx+oFSF1RfgAA
+lPra4OiszU2H/arMBBwTVgAA
+4
+6joY7NxGn0ahIzUv8F22pwAA
+dJOe2AeIeUurT8IIpz869QAA
+cxdf5fynWEG7/Wzlz9wAZgAA
+COnrVcktJUCdGcPafp3OSAAA
+
+
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+qO84lDa9Q0qJdFLxAzRcQQAA
+6v13bJAx1kq9YduccEEU9gAA
+ZMzpEg3HoEqa10tH7B2G8wAA
+o11tppkaYkmmUpyKj45BzAAA
+2
+
+zHN3b0KW5kCvSqS/RtHanwAA
+g0zWWZA9xEWvFh0sRnmMqgAA
+4
+6HcxdQob+UOT1wCYJ4QeHgAA
+MfI12JH1kkSbXGyVvMqqXQAA
+tMamOzqFxk6hZeNgqluobwAA
+/ARNc/hPvUmBl4qb/XiPqQAA
+
+
+akAggregate
+zHN3b0KW5kCvSqS/RtHanwAA
+q11CD3et4kixnDRLW4nPdgAA
+4
+ymxDIXyVUESDyLIcICrGWQAA
+9JS131H/4US3bVVB0X+RIAAA
+I8zAzIUs30G8GAyGAkzPOAAA
+itBAlqtdlUK0IXNYnX3+mQAA
+
+
+
+creates
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+iyKZKLbxiESYfeiNMEfWLgAA
+XWmIOlAy8Eexc2A3fTOWPQAA
+eEvmFxzBgkKlJ6XZoJKLxQAA
+SPWavA2MwUqTfTnCvOFgkAAA
+2
+
+False
+FJ1X3D9c80uG5EgY7ATqzQAA
+rDKOyCdZEkCOx+oFSF1RfgAA
+4
+hIeXX5pEhk+9J80xff/Z2QAA
+Jn/ACJad8kOY5lGCpXLetQAA
+USMA9tEXpkGY+pAIVRjLHAAA
+WNomTSYdhk6j1wGMK0aBMQAA
+
+
+FJ1X3D9c80uG5EgY7ATqzQAA
+JQvuxGbsdE2jFadShkxqKgAA
+4
+vMwGVXrxPkCKOvOAPR6ytQAA
+BAaRrPSiRkWfQQrnfeF5BQAA
+b6bOArvlz0+mgsrQHIOI8wAA
+rACoLZEoXESlgVdLXl1ocQAA
+
+
+
+SomePlugin
+NmvwO09X4Uu7xy6qNwdIDQAA
+1
+xW95yby7XEChYzUI8UtliAAA
+
+
+ConE
+NmvwO09X4Uu7xy6qNwdIDQAA
+1
+Nppn0CUEP0Stsi3DAR1qEQAA
+
+
+uses
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+bXvOSs/6UES15aDKmn3tXwAA
+L9RK4KdHs0+ZCinhj9kSUQAA
+A+D5vQx9bkm3AkTkaVYCZwAA
+fupy5ZQhwkmHjREiTpmstwAA
+2
+
+False
+C72p+KeoXkaRHqlZwhKDHgAA
+q11CD3et4kixnDRLW4nPdgAA
+4
+YQ4SH0PbkU6D2Ed6kFWZ3gAA
+au7s+O1a6EOhU92BZ9mTfAAA
+uC7b5/Ag8E+lVXijU0puEAAA
+SutSAX/p70WlhiBCYP5mIQAA
+
+
+C72p+KeoXkaRHqlZwhKDHgAA
+3dlH2vm6sEayyvEaXZoCngAA
+4
+Rn+WUty/KE6o3UWIZm/++wAA
+7gOWzEGpb0KSajbXDeX03QAA
+e/X32+GrOUiRRJMneGhhrwAA
+1RN9/oe60kCHXG3xE2fYmQAA
+
+
+
+uses
+NmvwO09X4Uu7xy6qNwdIDQAA
+4
+s/hl5J8Ex0WfRP8M9AKteQAA
+cHQJb0VhkEaKSG9FNZH8ywAA
+NIiBXFgih0OcuF+WiDNxzQAA
+f5/Uw2VFyEy4ygXzpaawvwAA
+2
+
+False
+zR4RT17TyUGNWLtHCk4EHQAA
+3dlH2vm6sEayyvEaXZoCngAA
+4
+Ao1mzGyZkUOXJ7iUZ+CxmQAA
+Mlo0JoqcnUWmKG46gdW/pgAA
+60bFmV8mJ02N5+zPFmP+cAAA
+hQN6K9SliEunBHaWLwTWywAA
+
+
+zR4RT17TyUGNWLtHCk4EHQAA
+rDKOyCdZEkCOx+oFSF1RfgAA
+4
+65oSMAg0mkmODMiMbf+UjQAA
+6vvMJYaqA0+EsdkZT8o6oAAA
+znikN5jxMkWgoTVeUx7U0wAA
+AnbfKLYaZ0qC8tWUwfnFkgAA
+
+
+1
+
+CollaborationInstanceSet1
+NmvwO09X4Uu7xy6qNwdIDQAA
+1
+
+InteractionInstanceSet1
+wE9rci0vbESzsZiTNus9aQAA
+1
+
+plugin_lifecycle
+g7HC4cn5j0ePStV0Z8NLZQAA
+
+MweH+mHn6EG06i4RV2qaAwAA
+14
+
+clMaroon
+$00B9FFFF
+496
+44
+91
+501
+hQik1kfcpkyjWa8YrxUXVwAA
+
+
+4
+SomeImplReader
+
+
+False
+
+
+False
+
+
+
+hQik1kfcpkyjWa8YrxUXVwAA
+
+
+
+clMaroon
+$00B9FFFF
+264
+44
+70
+492
+jSHc3saXOkOAzxbvtSSvXgAA
+
+
+4
+SomeImpl
+
+
+False
+
+
+False
+
+
+
+jSHc3saXOkOAzxbvtSSvXgAA
+
+
+
+clMaroon
+$00B9FFFF
+60
+44
+70
+484
+lHd6qkmEfEG1mu2rVzLWvQAA
+
+
+4
+ConE
+
+
+False
+
+
+False
+
+
+
+lHd6qkmEfEG1mu2rVzLWvQAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+95,104;534,104
+ETeRfxsNA0WrWaitgSd5aAAA
+iTZB2Agt80qwISCz0GsacAAA
+lgxda+WlMEubY4kveLQrHQAA
+
+0.154996718091723
+64.7765389628066
+1 : read_impl()
+ETeRfxsNA0WrWaitgSd5aAAA
+ZzClt2lwX0ur1JiJU0VhlgAA
+
+
+False
+1.5707963267949
+25
+ETeRfxsNA0WrWaitgSd5aAAA
+ZzClt2lwX0ur1JiJU0VhlgAA
+
+
+False
+-1.5707963267949
+10
+ETeRfxsNA0WrWaitgSd5aAAA
+ZzClt2lwX0ur1JiJU0VhlgAA
+
+
+534
+104
+14
+53
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+534,148;305,148
+vXwKExFme0SCDlJgwAIMdwAA
+76HsHUrPOkK3WaYC5FDF9gAA
+iTZB2Agt80qwISCz0GsacAAA
+
+1.5707963267949
+10
+2
+vXwKExFme0SCDlJgwAIMdwAA
+iWpnJYmQZ06zp9jeI3zllwAA
+
+
+1.5707963267949
+25
+<<create>>
+vXwKExFme0SCDlJgwAIMdwAA
+iWpnJYmQZ06zp9jeI3zllwAA
+
+
+False
+-1.5707963267949
+10
+vXwKExFme0SCDlJgwAIMdwAA
+iWpnJYmQZ06zp9jeI3zllwAA
+
+
+292
+148
+14
+373
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+95,176;299,176
+ScBrhUBtKEeVH+NRokpoRgAA
+76HsHUrPOkK3WaYC5FDF9gAA
+lgxda+WlMEubY4kveLQrHQAA
+
+1.5707963267949
+10
+3 : has_tag()
+ScBrhUBtKEeVH+NRokpoRgAA
++Ow+b/tIbUyKIrcZ30QMXwAA
+
+
+False
+1.5707963267949
+25
+ScBrhUBtKEeVH+NRokpoRgAA
++Ow+b/tIbUyKIrcZ30QMXwAA
+
+
+False
+-1.5707963267949
+10
+ScBrhUBtKEeVH+NRokpoRgAA
++Ow+b/tIbUyKIrcZ30QMXwAA
+
+
+299
+176
+14
+29
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+299,200;95,200
+hmREJ5ZnTEeAfrq77EpChAAA
+lgxda+WlMEubY4kveLQrHQAA
+76HsHUrPOkK3WaYC5FDF9gAA
+
+1.5707963267949
+10
+4 : True
+hmREJ5ZnTEeAfrq77EpChAAA
+99i+uHCR6E2zi1ljW6TfvwAA
+
+
+False
+1.5707963267949
+25
+hmREJ5ZnTEeAfrq77EpChAAA
+99i+uHCR6E2zi1ljW6TfvwAA
+
+
+False
+-1.5707963267949
+10
+hmREJ5ZnTEeAfrq77EpChAAA
+99i+uHCR6E2zi1ljW6TfvwAA
+
+
+False
+95
+200
+14
+29
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+95,257;299,257
+HCFFRuQKg0CdJr76tbmjmwAA
+76HsHUrPOkK3WaYC5FDF9gAA
+lgxda+WlMEubY4kveLQrHQAA
+
+1.5707963267949
+10
+5 : has_ref()
+HCFFRuQKg0CdJr76tbmjmwAA
+749elK1zJ02MBLlaR2EcPgAA
+
+
+False
+1.5707963267949
+25
+HCFFRuQKg0CdJr76tbmjmwAA
+749elK1zJ02MBLlaR2EcPgAA
+
+
+False
+-1.5707963267949
+10
+HCFFRuQKg0CdJr76tbmjmwAA
+749elK1zJ02MBLlaR2EcPgAA
+
+
+299
+257
+14
+32
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+299,280;95,280
+FL5rZMXYGEyb7KN5v8T0PgAA
+lgxda+WlMEubY4kveLQrHQAA
+76HsHUrPOkK3WaYC5FDF9gAA
+
+1.5707963267949
+10
+6 : True
+FL5rZMXYGEyb7KN5v8T0PgAA
+uaIw94jxekqP0W98wtudsQAA
+
+
+False
+1.5707963267949
+25
+FL5rZMXYGEyb7KN5v8T0PgAA
+uaIw94jxekqP0W98wtudsQAA
+
+
+False
+-1.5707963267949
+10
+FL5rZMXYGEyb7KN5v8T0PgAA
+uaIw94jxekqP0W98wtudsQAA
+
+
+False
+95
+280
+14
+29
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+95,326;299,326
+xZNxieQfVEi96d0Po7wuIgAA
+76HsHUrPOkK3WaYC5FDF9gAA
+lgxda+WlMEubY4kveLQrHQAA
+
+1.5707963267949
+10
+7 : invocation_phase()
+xZNxieQfVEi96d0Po7wuIgAA
+HitDDnXBMkeQgf4Xefc6nQAA
+
+
+False
+1.5707963267949
+25
+xZNxieQfVEi96d0Po7wuIgAA
+HitDDnXBMkeQgf4Xefc6nQAA
+
+
+False
+-1.5707963267949
+10
+xZNxieQfVEi96d0Po7wuIgAA
+HitDDnXBMkeQgf4Xefc6nQAA
+
+
+299
+326
+14
+31
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+299,353;95,353
+lz53uWB/xkyYZ3lvk/DtaAAA
+lgxda+WlMEubY4kveLQrHQAA
+76HsHUrPOkK3WaYC5FDF9gAA
+
+1.5707963267949
+10
+8 : "normal"
+lz53uWB/xkyYZ3lvk/DtaAAA
+i0ubsfTqFUuhFGuTgGUl5gAA
+
+
+False
+1.5707963267949
+25
+lz53uWB/xkyYZ3lvk/DtaAAA
+i0ubsfTqFUuhFGuTgGUl5gAA
+
+
+False
+-1.5707963267949
+10
+lz53uWB/xkyYZ3lvk/DtaAAA
+i0ubsfTqFUuhFGuTgGUl5gAA
+
+
+False
+95
+353
+14
+29
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+95,404;292,404
+2eiKgeafeEmhRL09/pvPdQAA
+76HsHUrPOkK3WaYC5FDF9gAA
+lgxda+WlMEubY4kveLQrHQAA
+
+1.5707963267949
+10
+9 : set generation_context
+2eiKgeafeEmhRL09/pvPdQAA
+a3V6pkBtlkaN5lCa6quFRAAA
+
+
+False
+1.5707963267949
+25
+2eiKgeafeEmhRL09/pvPdQAA
+a3V6pkBtlkaN5lCa6quFRAAA
+
+
+False
+-1.5707963267949
+10
+2eiKgeafeEmhRL09/pvPdQAA
+a3V6pkBtlkaN5lCa6quFRAAA
+
+
+False
+292
+404
+14
+29
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+95,440;299,440
+35X3nu8KkUSR9OsWOqVq3wAA
+76HsHUrPOkK3WaYC5FDF9gAA
+lgxda+WlMEubY4kveLQrHQAA
+
+1.5707963267949
+10
+10 : generate()
+35X3nu8KkUSR9OsWOqVq3wAA
+2bYCKznAnk+rS9pJ3kfo4QAA
+
+
+False
+1.5707963267949
+25
+35X3nu8KkUSR9OsWOqVq3wAA
+2bYCKznAnk+rS9pJ3kfo4QAA
+
+
+False
+-1.5707963267949
+10
+35X3nu8KkUSR9OsWOqVq3wAA
+2bYCKznAnk+rS9pJ3kfo4QAA
+
+
+299
+440
+14
+29
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+95,480;299,480
+Aq0JDBAyG0OKfOPyRy4jKAAA
+76HsHUrPOkK3WaYC5FDF9gAA
+lgxda+WlMEubY4kveLQrHQAA
+
+1.5707963267949
+10
+11 : post_generate()
+Aq0JDBAyG0OKfOPyRy4jKAAA
+ekbq9rF6QEeW0pNl4NQ76AAA
+
+
+False
+1.5707963267949
+25
+Aq0JDBAyG0OKfOPyRy4jKAAA
+ekbq9rF6QEeW0pNl4NQ76AAA
+
+
+False
+-1.5707963267949
+10
+Aq0JDBAyG0OKfOPyRy4jKAAA
+ekbq9rF6QEeW0pNl4NQ76AAA
+
+
+299
+480
+14
+29
+
+
+
+
+11
+
+read_impl
+lHd6qkmEfEG1mu2rVzLWvQAA
+hQik1kfcpkyjWa8YrxUXVwAA
+
+ETeRfxsNA0WrWaitgSd5aAAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+ZzClt2lwX0ur1JiJU0VhlgAA
+fgeDv7FmBUeP3cp7diyX6gAA
+RYBTEUdOrESltsSnvX+NqwAA
+TTG4jdnwm0GaKQH6SxMbswAA
+
+
+hQik1kfcpkyjWa8YrxUXVwAA
+jSHc3saXOkOAzxbvtSSvXgAA
+
+vXwKExFme0SCDlJgwAIMdwAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+iWpnJYmQZ06zp9jeI3zllwAA
+SHiSVWWFe0iFY9H6k3/NgAAA
+e2rGfofWfkOI/nDlEH4OAwAA
+OUCHbgoT/UigIAbkVywfLgAA
+
+
+has_tag
+lHd6qkmEfEG1mu2rVzLWvQAA
+jSHc3saXOkOAzxbvtSSvXgAA
+
+ScBrhUBtKEeVH+NRokpoRgAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
++Ow+b/tIbUyKIrcZ30QMXwAA
+Bx4xnq8PrEaR406zvi4+EwAA
+nGuJvJRER0KwPOHLpJhcMAAA
+DQieJ421M0K20EZbYakf1QAA
+
+
+True
+jSHc3saXOkOAzxbvtSSvXgAA
+lHd6qkmEfEG1mu2rVzLWvQAA
+
+hmREJ5ZnTEeAfrq77EpChAAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+99i+uHCR6E2zi1ljW6TfvwAA
+pHlZQddy+UG//3HPLRlQdQAA
+AZ6lFTJhzk2PSYFvZKecxQAA
+ajQ6tnwcxUaHuThis4tXPwAA
+
+
+has_ref
+lHd6qkmEfEG1mu2rVzLWvQAA
+jSHc3saXOkOAzxbvtSSvXgAA
+
+HCFFRuQKg0CdJr76tbmjmwAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+749elK1zJ02MBLlaR2EcPgAA
+z+twBvUeW0yPZPAijtHYtgAA
+ArEQ2HcAUEmKPLhuixIA2gAA
+XGJYGt02q0aSCp/onBf0OQAA
+
+
+True
+jSHc3saXOkOAzxbvtSSvXgAA
+lHd6qkmEfEG1mu2rVzLWvQAA
+
+FL5rZMXYGEyb7KN5v8T0PgAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+uaIw94jxekqP0W98wtudsQAA
+N54sAOjMjkmtsRpnPb0JbQAA
+D9r3Ws7M5ku1FnM+Nx1w8gAA
+Q/rG0aY0qUSMCsO+ilBwBgAA
+
+
+invocation_phase
+lHd6qkmEfEG1mu2rVzLWvQAA
+jSHc3saXOkOAzxbvtSSvXgAA
+
+xZNxieQfVEi96d0Po7wuIgAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+HitDDnXBMkeQgf4Xefc6nQAA
+ICT9zXXLAEyZa+aj37ySZAAA
+khYwlPKhOEGqTf16sLmysgAA
+K39TzHEoekqbm38UKrrR+gAA
+
+
+"normal"
+jSHc3saXOkOAzxbvtSSvXgAA
+lHd6qkmEfEG1mu2rVzLWvQAA
+
+lz53uWB/xkyYZ3lvk/DtaAAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+i0ubsfTqFUuhFGuTgGUl5gAA
+y1YMAKKX10aSMf8sWWG/OwAA
+FFQFtf3eDkW/R9CpgMLFUgAA
+4xNdXZrVgUCeyyqbXVpdYQAA
+
+
+set generation_context
+lHd6qkmEfEG1mu2rVzLWvQAA
+jSHc3saXOkOAzxbvtSSvXgAA
+
+2eiKgeafeEmhRL09/pvPdQAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+a3V6pkBtlkaN5lCa6quFRAAA
+RScoZcFAOkGMMFrCICgbewAA
+M0Q6Xg6CRUGUwdR0rL6jAQAA
+vBUjGOYNiEusPMmq7qgZvAAA
+
+
+generate
+lHd6qkmEfEG1mu2rVzLWvQAA
+jSHc3saXOkOAzxbvtSSvXgAA
+
+35X3nu8KkUSR9OsWOqVq3wAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+2bYCKznAnk+rS9pJ3kfo4QAA
+2j/5XixvA0ieCFGpEhnSaAAA
+pTrvJzdmnEWH7QSEQe4rOwAA
+ehp6Xzgo7EmHUdpvKRua/wAA
+
+
+post_generate
+lHd6qkmEfEG1mu2rVzLWvQAA
+jSHc3saXOkOAzxbvtSSvXgAA
+
+Aq0JDBAyG0OKfOPyRy4jKAAA
+
+g7HC4cn5j0ePStV0Z8NLZQAA
+4
+ekbq9rF6QEeW0pNl4NQ76AAA
+UegBZ8wW8keFY2Jjh+bxOAAA
+JV7Ah/5/kkO1Q7WX0tPfaAAA
+DgX+SZarPkKJULR5l9fahgAA
+
+
+3
+
+SomeImplReader
+wE9rci0vbESzsZiTNus9aQAA
+2
+PoPtpN50LU6FA7qmOri9aAAA
+iTZB2Agt80qwISCz0GsacAAA
+1
+vXwKExFme0SCDlJgwAIMdwAA
+1
+ETeRfxsNA0WrWaitgSd5aAAA
+
+
+SomeImpl
+wE9rci0vbESzsZiTNus9aQAA
+2
+J22BJLGC2EurOQxtPclM2gAA
+76HsHUrPOkK3WaYC5FDF9gAA
+3
+hmREJ5ZnTEeAfrq77EpChAAA
+FL5rZMXYGEyb7KN5v8T0PgAA
+lz53uWB/xkyYZ3lvk/DtaAAA
+7
+vXwKExFme0SCDlJgwAIMdwAA
+ScBrhUBtKEeVH+NRokpoRgAA
+HCFFRuQKg0CdJr76tbmjmwAA
+xZNxieQfVEi96d0Po7wuIgAA
+2eiKgeafeEmhRL09/pvPdQAA
+35X3nu8KkUSR9OsWOqVq3wAA
+Aq0JDBAyG0OKfOPyRy4jKAAA
+
+
+ConE
+wE9rci0vbESzsZiTNus9aQAA
+2
+tse6Or/GkEify2aNOl5gMAAA
+lgxda+WlMEubY4kveLQrHQAA
+7
+ETeRfxsNA0WrWaitgSd5aAAA
+ScBrhUBtKEeVH+NRokpoRgAA
+HCFFRuQKg0CdJr76tbmjmwAA
+xZNxieQfVEi96d0Po7wuIgAA
+2eiKgeafeEmhRL09/pvPdQAA
+35X3nu8KkUSR9OsWOqVq3wAA
+Aq0JDBAyG0OKfOPyRy4jKAAA
+3
+hmREJ5ZnTEeAfrq77EpChAAA
+FL5rZMXYGEyb7KN5v8T0PgAA
+lz53uWB/xkyYZ3lvk/DtaAAA
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/example-plugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/example-plugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,284 @@
+.. _plugin-howto-example-plugin:
+
+Example plug-in
+===============
+
+The example plug-in implements a simple Implementation Markup Language that can write
+text files with possibly some content coming from ConfML setting values. The plug-in
+demonstrates some recommended practices for developing ConE plug-ins:
+
+- Plug-in structure:
+ - Reader class
+ - Implementation class
+ - Implementation model
+- Using ``cone.public.utils`` for ConfML setting reference handling
+- Unit tests:
+ - Testing the reader class, the implementation class and the model classes separately
+ - Output generation testing (plug-in scope integration test)
+
+The ExampleML language
+----------------------
+
+The Implementation Markup Language in the example plug-in is ExampleML. The language
+offers a simple mechanism to write text files to the output directory. For example:
+
+.. code-block :: xml
+
+
+
+ Test
+ Test
+
+
+To demonstrate the use of ConfML setting references, the language supports also
+those with the form ``${Feature.Setting}``. This is the usual way of using them
+in implementation languages, and it is recommended to use the same convention
+in all ImplMLs. For example:
+
+.. code-block :: xml
+
+
+
+
+ Value from ConfML: ${SomeFeature.OutputText}
+
+
+
+.. _plugin-howto-example-plugin-dir-structure:
+
+Directory structure
+-------------------
+
+- ``plugins/`` - Root directory for all ConE plug-in sources
+ - ``example/`` - Example plug-in package directory
+ - ``ConeExamplePlugin/`` - Source for the example plug-in
+ - ``examplemlplugin/`` - Module directory containing all plug-in code
+ - ``tests/`` - Unit tests and test data for the plug-in
+ - ``project/`` - Configuration project used in the tests
+ - ``gen_expected/`` - Expected output for generation test case
+ - ``__init__.py`` - Test module initialization file
+ - ``runtests.py`` - Script for running all test cases
+ - ``unittest_exampleml_impl.py`` - File containing test cases
+ - ``unittest_exampleml_reader.py`` - File containing test cases
+ - ``unittest_exampleml_generation.py`` - File containing test cases
+ - ``__init__.py`` - Plug-in module initialization file
+ - ``exampleml_impl.py`` - Plug-in source file
+ - ``exampleml_reader.py`` - Plug-in source file
+ - ``setup.py`` - Setup script for packaging the plug-in into an .egg file
+ - ``setup.cfg`` - Configuration file for ``setup.py``
+ - ``integration-test/`` - Integration tests for the example plug-in package
+ - ``testdata/`` - Test data for the integration tests
+ - ``__init__.py`` - Test module initialization file
+ - ``runtests.py`` - Script for running all test cases
+ - ``export_standalone.py`` - Script for exporting extra data for standalone test export
+ - ``unittest_generate.py`` - File containing test cases
+
+Logical structure
+-----------------
+
+Logically the plug-in is divided into three parts:
+
+- *Implementation model*, represents the logical model of the implementation specified in the XML data
+- *Implementation class*, works as the interface of the plug-in towards ConE and uses the model to do the actual work
+- *Implementation reader*, converts the XML data into the logical model and creates a new implementation class instance
+
+In this case the *model* consists just of the class Output, which corresponds to the ```` element.
+
+Plug-in code
+------------
+
+exampleml_model.py
+..................
+
+This file defines the ``Output`` class, which comprises the whole implementation model
+in this case. The class contains the same attributes as its XML element counterpart:
+file, encoding and text, as well as the methods for generating output from the
+``Output`` object.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_model.py
+ :linenos:
+
+Notice the use of ``cone.public.utils`` to handle the ConfML settings references. Usage of
+setting refs is common enough to warrant a set of functions related to their handling in ``utils``.
+It is strongly recommended to use these utility functions instead of creating your own.
+
+.. note::
+
+ The expanding of ConfML setting references is done here, in the ``Output`` object, instead of in the reader
+ when the implementation is parsed. If it was done in the parsing phase, ConfML setting values changed
+ in rules would not be expanded to their new values.
+
+Another noteworthy thing is that the ``Output`` class implements the methods ``__eq__()``,
+``__ne__()`` and ``__repr__()``. These have no real use in the actual implementation, but they
+make unit testing easier, as will be seen later on.
+
+The logic for creating the output is here encoded directly in the model, but in cases where
+the model is more complex, it may be necessary to create a separate writer class, particularly
+if there is more than one output format to be created based on the same model.
+
+exampleml_impl.py
+.................
+
+This file defines the implementation class. As can be seen, the class is quite simple, since
+it uses the model class to do the actual work and only works as an interface towards ConE.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_impl.py
+ :linenos:
+
+exampleml_reader.py
+...................
+
+This file defines the reader class. Note how the reading of a single element is given its
+own method. Again, this is to make unit testing easier.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py
+ :linenos:
+
+
+Unit tests
+----------
+
+Due to the dynamic nature of Python, an extensive set of unit tests is required for every plug-in.
+The unit tests for a ConE plug-in should be in a ``tests`` module (directory) under the plug-in's
+main module directory, and contain a set ``unittests_*.py`` files. The naming here is important,
+since the ``runtests.py`` file used to run all the unit tests at once collects test cases only
+from .py files starting with ``unittest_``.
+
+Unit tests can be executed by running each individual unit test file separately using "Run as" -> "Python unit-test" or
+all of the plug-in's unit tests at once by using "Run as" -> "Python run" on ``runtests.py``.
+
+.. image:: run_unittest.png
+
+*Running a single unit test file*
+
+It is recommended (well, actually required) to make sure that all unit tests pass before committing changes made to
+the code of any plug-in. Also, it should be checked that all of the plug-in's unit tests pass when run as part
+of all plug-in unit tests. It is possible that tests that pass when running ``runtests.py`` fail when running them
+as part of the whole plug-in test set, as in that case the working directory is not the same. The entire plug-in test
+set can be run from ``source/plugins/tests/runtests.py``.
+
+
+unittest_exampleml_reader.py
+............................
+
+This file tests that the reader class functions properly. See how there is a test case for reading
+a single ```` element that tests all the special cases there, and then another that
+tests the top-level reader method. Here it becomes obvious why it is worthwhile to implement the
+``__eq__()`` etc. methods in model classes, as in the tests we can just give the parser an XML
+string and specify exactly what kind of a Python object is expected to be parsed from it.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_reader.py
+ :linenos:
+
+unittest_exampleml_impl.py
+..........................
+
+This file tests that the implementation class works as expected. The methods to test are ``has_ref()``
+and ``list_output_files()``, since it is vital for the plug-in's correct operation that these methods
+do what they are supposed to. Note that ``generate()`` is not tested here, as it is tested in its own
+file.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_impl.py
+ :linenos:
+
+unittest_exampleml_generation.py
+................................
+
+This file tests that the plug-in works correctly throughout its lifecycle, so it works as an integration test.
+Note that plug-in instances are not created manually, but an implementation container is created from the project.
+This means that the test also makes sure that the plug-in interoperates correctly with ConE's plug-in machinery.
+
+Also note that the output is checked against an expected set of files using the method ``assert_dir_contents_equal()``,
+which comes from a unit test base class defined in a special ``testautomation`` module. This module contains also other
+helper methods for use in unit tests, so if you need something more sophisticated than the simple methods provided
+by the ``unittest`` module, you should check the ``testautomation`` module before writing the methods yourself.
+The module can be found under ``source/``.
+
+Notice also how the generation output directory is set to be in a ``temp/`` directory in the same directory
+as the test .py file is. It is recommended to keep all temporary test data in a single place like this, so that
+they don't litter e.g. the current working directory. When using a single ``temp/`` directory, it can also be
+ignored in version control to avoid unnecessarily listing the temporary data when checking for modification in
+the workding copy.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py
+ :linenos:
+
+Plug-in packaging
+-----------------
+
+The file ``setup.py`` handles the packaging of the plug-in into an egg file.
+
+The most important thing here is the plug-in's entry point info. The
+plug-in's reader classes must be specified as entry points, or they won't be
+loaded.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/setup.py
+ :linenos:
+
+
+.. _plugin-howto-example-plugin-integration-tests:
+
+Integration tests
+-----------------
+
+In addition to the unit tests inside the plug-in itself there is a separate integration test set.
+The purpose of these tests is to make sure that the plug-ins in the package work properly
+together with other implementations from the CLI level. E.g. a common case that is good to
+test is to check that ConfML settings changed in rules affect the implementations using
+references to those settings work properly.
+
+These tests are also exported as part of the standalone test set used to test a pre-built
+ConE distribution (see :ref:`installation-export-tests`). This affects the way some things
+are handled in the test cases, for example the way the command to run is determined.
+
+The integration test set is plug-in package specific, not plug-in specific, so the test
+project(s) used there should contain implementations of all the implementation languages
+provided by the plug-ins in the package. Of course, in this case there are only ExampleML
+implementations, since the example plug-in is the only plug-in in the example package.
+
+runtests.py
+...........
+
+This file simply acts as a shortcut to run all test cases easily.
+
+__init__.py
+...........
+
+This file performs all integration test specific initialization using the plug-in utility
+functions in the root ``plugins/`` directory. Note that when the integration test set is
+exported as standalone, the contents of this file are erased (the integration test
+initialization cannot be done there, since the full ConE source is not available). Because
+of this, you should not put anything that is always needed in this file.
+
+export_standalone.py
+....................
+
+This file contains a function for exporting any needed extra data into the standalone test
+set (e.g. something from under the plug-in sources). The file doesn't necessarily need to
+exist if there is no extra data in need of exporting, but in this example it exists to show
+what could be done in it.
+
+.. literalinclude:: /../source/plugins/example/integration-test/export_standalone.py
+ :linenos:
+
+unittest_generate.py
+....................
+
+This file contains tests for generating output using the example plug-in.
+Note the following things:
+
+- The use of the variable ``CONE_CMD`` in ``get_cmd()``. This variable is set to
+ contain the actual ConE command to run if the tests are being run from the
+ exported standalone test set. In practice this will be something like
+ ``C:/cone_test/cone/cone.cmd``.
+- The actual generation and testing is done in a separate function, ``run_test_generate()``,
+ and there are two actual test functions that call it. One runs the test directly on the
+ test project on the file system, and another first zips the test project and then runs
+ the test on that. It is a good idea to test that generation works the same in both cases,
+ since it can be easy to forget to take into account generation from a ZIP file when creating
+ a plug-in (e.g. using ``shutil`` functions to perform copy operations when the ConE API
+ should be used).
+
+.. literalinclude:: /../source/plugins/example/integration-test/unittest_generate.py
+ :linenos:
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/index.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/index.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+.. _plugin-howto:
+
+How to create a ConE plug-in
+============================
+
+This page contains a description of ConE's plug-in interface, a description of
+an example plug-in intended to be used as a template for creating new plug-ins,
+and step-by-step instructions for creating a new ConE plug-in based on the template.
+The impatient can simply skip to the step-by-step instructions, by it is recommended
+to read the also the plug-in interface and example plug-in descriptions.
+
+The instructions assume that the used development environment is Eclipse/PyDev.
+
+.. toctree::
+ :maxdepth: 3
+
+ plugin-interface
+ example-plugin
+ steps
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/plugin-interface.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/plugin-interface.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,200 @@
+.. _plugin-howto-plugin-interface:
+
+Plug-in interface
+=================
+
+A ConE plug-in has two points for interfacing with ConE:
+
+#. Reader classes that derive from ``cone.public.plugin.ReaderBase`` . These classes
+ define supported Implementation Markup Languages (i.e. supported XML namespaces)
+ and other attributes related to them like file extensions. As the name suggests, they are
+ also responsible for reading implementation instances from XML data.
+#. Implementation classes that derive from ``cone.public.plugin.ImplBase``. These classes
+ supply the actual run-time functionality of the plug-ins.
+
+The following UML diagram shows the most important classes and their interdependencies:
+
+.. image:: plugin_classes.jpg
+
+ConE generation can be seen to consist of two phases, implementation parsing
+and output generation:
+
+Parsing phase:
+
+- Implementation file list is filtered based on a user-given file name pattern
+ and supported file extensions
+- All remaining files are parsed into ``ElementTree`` instances
+- The ``ElementTree`` instance is scanned for supported ImplML namespaces and
+ implementation instances are created using the correct reader classes
+ (the ``read_impl()`` method)
+- All implementations are collected into an ``ImplSet`` instance
+
+Generation phase:
+
+- Implementation instances are further filtered using tags and ConfML references
+ (the ``has_tag()`` and ``has_ref()`` methods)
+- Implementations instances are divided into separate sets based on their invocation
+ phases
+- Output is generated using each implementation set. For each implementation set:
+
+ - The ``generation_context`` variable of each implementation instance is set
+ (this context contains generation-scope information implementations instances may use)
+ - The ``generate()`` method of each instance is called
+ - The ``post_generate()`` method of each instance is called
+
+From a plug-in's point of view, the sequence of method calls goes as follows:
+
+.. image:: plugin_lifecycle.jpg
+
+Explanations of the steps in the diagram:
+
+====== ========================================================================
+Step Explanation
+====== ========================================================================
+1 ``read_impl()`` is called to create an implementation instance based on
+ XML data.
+2 ``read_impl()`` creates the instance.
+3-6 Filtering based on ConfML references and implementation tags is done.
+ The implementation instance returns True in all cases, so it is included
+ in the actual generation.
+7-8 The instance is asked for its invocation phase (here it returns "normal")
+9 The implementation instance's ``generation_context`` variable is set, so
+ then it can be used in the actual generation.
+10-11 Output generation methods are called
+====== ========================================================================
+
+Plug-in interface class source
+------------------------------
+
+The following source listings show the most important parts of the ``ImplReader``
+and ``ImplBase`` classes from a plug-in's point of view:
+
+.. code-block:: python
+
+ class ReaderBase(object):
+ """
+ Base class for implementation readers.
+
+ Each reader class supports one XML namespace, from which it reads an implementation
+ instance.
+
+ The method for parsing an implementation (read_impl()) is given an ElementTree
+ XML element as the root from which to parse the implementation. The plug-in
+ machinery handles each XML file so that the correct reader class is used to read
+ the implementations from XML elements based on the namespaces.
+ """
+
+ # The XML namespace supported by the implementation reader.
+ # Should be something like "http://www.xyz.org/xml/1".
+ # Can also be None, in which case the reader will not be used
+ # (this can be useful for defining base classes for e.g. readers
+ # for different versions of an implementation).
+ NAMESPACE = None
+
+ # Any extra XML namespaces that should be ignored by the
+ # implementation parsing machinery. This is useful for specifying
+ # namespaces that are not actual ImplML namespaces, but are used
+ # inside an implementation (e.g. XInclude)
+ IGNORED_NAMESPACES = []
+
+ # Supported implementation file extensions.
+ # Sub-classes can override this to add new supported file extensions
+ # if necessary. The file extensions simply control whether implementations
+ # are attempted to be read from a file or not.
+ # Note that the extensions are case-insensitive.
+ FILE_EXTENSIONS = ['implml']
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, doc_root):
+ """
+ Read an implementation instance from the given element tree.
+
+ @param resource_ref: Reference to the resource in the configuration in
+ which the given document root resides.
+ @param configuration: The configuration used.
+ @param doc_root: The document root from which to parse the implementation.
+ @return: The read implementation instance, or None.
+ """
+ raise exceptions.NotSupportedException()
+
+.. code-block:: python
+
+ class GenerationContext(object):
+ """
+ Context object that can be used for passing generation-scope
+ data to implementation instances.
+ """
+
+ def __init__(self, tags={}):
+ # The tags used in this generation context
+ # (i.e. the tags passed from command line)
+ self.tags = tags
+
+ # A dictionary that implementation instances can use to
+ # pass any data between each other
+ self.impl_data_dict = {}
+
+.. code-block:: python
+
+ class ImplBase(object):
+ """
+ Base class for any confml implementation.
+ """
+
+ # Identifier for the implementation type, used e.g. in .cfg files.
+ # Should be a string like e.g. 'someml'.
+ IMPL_TYPE_ID = None
+
+ # Defines the default invocation phase for the implementation.
+ # The default is used if the phase is not explicitly set in the
+ # ImplML file or manually overridden by calling set_invocation_phase()
+ DEFAULT_INVOCATION_PHASE = None
+
+ def __init__(self,ref, configuration):
+ """
+ Create a ImplBase object
+ @param ref : the ref to the Implml file resource.
+ @param configuration : the Configuration instance for the
+ configuration data.
+ """
+ self._settings = None
+ self.ref = ref
+ self.index = None
+ self.configuration = configuration
+ self.output_root = self.settings.get('output_root','output')
+ self.output_subdir = self.settings.get('output_subdir','')
+ self.plugin_output = self.settings.get('plugin_output','')
+
+ self.generation_context = None
+ self._tags = None
+ self._invocation_phase = None
+ self._tempvar_defs = []
+
+ def generate(self):
+ """
+ Generate the given implementation.
+ @return:
+ """
+ raise exceptions.NotSupportedException()
+
+ def post_generate(self):
+ """
+ Called when all normal generation has been done.
+
+ @attention: This is a temporary method used for implementing cenrep_rfs.txt generation.
+ """
+ pass
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ raise exceptions.NotSupportedException()
+
+ def get_refs(self):
+ """
+ Return a list of all ConfML setting references that affect this
+ implementation. May also return None if references are not relevant
+ for the implementation.
+ """
+ return None
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/plugin_classes.jpg
Binary file configurationengine/doc/plugins/dev-plugin/plugin_classes.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/plugin_lifecycle.jpg
Binary file configurationengine/doc/plugins/dev-plugin/plugin_lifecycle.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/run_unittest.png
Binary file configurationengine/doc/plugins/dev-plugin/run_unittest.png has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/dev-plugin/steps.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/steps.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,48 @@
+.. _plugin-howto-steps:
+
+Step-by-step instructions for creating a new plug-in based on the example
+=========================================================================
+
+This page provides step-by-step instructions for creating a new plug-in based on the example
+plug-in described in :ref:`plugin-howto-example-plugin`. The new plug-in will simply be exactly the same as the example plug-in, except that
+the name will be changed from ExampleML to NewML.
+
+These steps show how to create a new plug-in under the ``example`` plug-in package, but the instructions
+can be used for creating an entirely new plug-in package also. To do that, simply export
+``source/plugins/example`` into ``source/plugins/new`` instead of just ``source/plugins/example/ConeExamplePlugin``
+into ``source/plugins/example/ConeNewPlugin``.
+
+#. Export the example plug-in into the new plug-in path. With TortoiseSVN it can be done like this:
+ #. Open ``source/plugins/example`` in Windows Explorer
+ #. Drag'n'drop ``ConeExamplePlugin`` into the empty area using the right mouse button
+ #. Select "SVN export to here" from the pop-up menu
+ #. Select "Auto rename" from the dialog that pops up
+ #. After the export is done, rename "Export of ConeExamplePlugin" to "ConeNewPlugin"
+#. Refresh the ``plugins/`` directory in Eclipse
+#. Rename all files and folders containing "exampleml" to "newml" under ``ConeNewPlugin/``
+ - ``examplemlplugin/`` -> ``newmlplugin/``
+ - ``exampleml_impl.py`` -> ``newml_impl.py``
+ - ``tests/unittest_exampleml_generation.py`` -> ``tests/unittest_newml_generation.py``
+ - ``tests/project/Layer/implml/test.exampleml`` -> ``tests/project/Layer/implml/test.newml``
+ - etc.
+#. Change "exampleml" to "newml" inside all files
+ - Select "ConeNewPlugin" in the PyDev Package Explorer
+ - Press Ctrl+H to do a file search. Use the following options:
+ - Containing text: exampleml (case-insensitive)
+ - File name patterns: *
+ - Scope: Selected resources
+ - Change the string everywhere (use the same case convention, e.g. "exampleml_impl" -> "newml_impl" and "ExamplemlReader" -> "NewmlReader")
+#. Check that test cases are run correctly and they pass
+ #. Run ``source/plugins/example/ConeNewPlugin/newmlplugin/tests/runtests.py`` to check that all tests pass (all modules are found etc.)
+ #. Run ``source/plugins/example/runtests.py`` to check that all tests pass also from the plug-in package level
+#. Modify ``setup.py``
+#. Check that the new plug-in is present in a ConE installation created using the ``example`` plug-in package
+ #. Go to the working directory on the command line and run (remember to use forward slashes)::
+
+ install.cmd C:/cone_temp_or_whatever_dir example
+
+ #. Go to the temporary directory specified in the previous step and run::
+
+ cone info --print-supported-impls
+
+ #. Check that you can find the new namespace and file extension in the list of supported namespaces and file extensions
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/genconfml-plugin/gcfml.jpg
Binary file configurationengine/doc/plugins/genconfml-plugin/gcfml.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/genconfml-plugin/genconfml_example1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/genconfml-plugin/genconfml_example1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/genconfml-plugin/genconfml_example2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/genconfml-plugin/genconfml_example2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+ foobar
+
+
+ 123
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/genconfml-plugin/genconfml_example3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/genconfml-plugin/genconfml_example3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+ foobar
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/genconfml-plugin/genconfml_example4.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/genconfml-plugin/genconfml_example4.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+Iby file:
+data = VARIANT\private\2000BEE5\CamcorderData.xml \private\2000BEE5\CamcorderData.xml
+
+File system:
+\output\my_variant\private\2000BEE5\CamcorderData.xml
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/genconfml-plugin/genconfml_example5.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/genconfml-plugin/genconfml_example5.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/genconfml-plugin/genconfmlplugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/genconfml-plugin/genconfmlplugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,156 @@
+User guide for Generic Configuration File Markup Language (GenConfML) Plugin
+----------------------------------------------------------------------------
+
+Introduction
+'''''''''''''
+This page describes how to use and configure Generic Configuration File Markup Language
+(GenConfML) plugin fo ConE. GenConfML is one of the implementation mapping languages for
+Configuration Markup Language (ConfML). This plugin is used to generate arbitrary text file
+formats. Currently this language uses a `eXtensible Stylesheet Language Transformations
+(XSLT) `_ style sheet for generating a file for selected settings.
+Support for other style sheet or transformation mechanisms than
+`XSLT `_ could be added later.
+
+GenConfML files are executed by default in **normal** :ref:`invocation phase `.
+
+GenConfML
+'''''''''
+
+The GenConfML (Generic Configuration File ML) syntax is a extension of Configuration markup
+language (confml). The term in confml for this extension is implementation method language
+(implml), which in GenConfML case is a xml file.
+
+ * Namespace: ``http://www.s60.com/xml/genconfml/1``
+ * File extension: ``gcfml``
+
+.. note::
+
+ More information about :ref:`file extensions `.
+
+GenConfML Elements
+..................
+
+The GenConfML model is drawn out as a uml model in below picture.
+
+ .. image:: gcfml.jpg
+
+.. note::
+
+ GenConfML supports also common ImplML elements. More information about :ref:`ImplML elements ` .
+
+ Element
+**************
+
+The ``file`` element is the root element of the configuration, and acts as a container to the rest of the elements. Each
+generated file must be defined in its own Generic Configuration File XML file. The input file for XSLT processor is
+the Configuration ML file including only the data element containing values for all selected settings. Following XSLT
+output types are supported: XML, HTML, and text.
+
+Attributes
+++++++++++
+
+==================== ====================== ===============================================================================
+Attribute Required Description
+==================== ====================== ===============================================================================
+name Yes Defines a name of the output file. Can contain path that is used to create
+ subfolders under output directory.
+target No Defines a Symbian specific attribute for additional path information. Final
+ target path is a combination of target and name. The combined path is used in
+ output directory and in IBY file. If target attribute is not supported full
+ path can be defined also as a value of name attribute.
+==================== ====================== ===============================================================================
+
+
+Child Elements
+++++++++++++++
+
+==================== ====================== ===============================================================================
+Element Cardinality Description
+==================== ====================== ===============================================================================
+setting 0 .. * Defines a configuration setting reference that is used as an input in XSLT
+ prosessing.
+xsl:stylesheet 1 Defines stylesheet for XSLT processor.
+==================== ====================== ===============================================================================
+
+Example
++++++++
+
+.. code-block:: xml
+
+
+ ...
+
+
+
+ Element
+*****************
+
+Setting element is mandatory element containing the settings used in this transformation.
+
+
+Attributes
+++++++++++
+
+==================== ====================== ===============================================================================
+Attribute Required Description
+==================== ====================== ===============================================================================
+ref Yes Defines a Feature/setting reference pair. All settings inside one feature
+ can be selected by using Feature/*.
+==================== ====================== ===============================================================================
+
+Example
++++++++
+
+.. code-block:: xml
+
+
+
+
+ Element
+************************
+
+Xsl:stylesheet element defines the XSLT [3] stylesheet used to transform input data from ConfML to output file.
+
+The style sheet can be defined inside file element or in external file identified using stylesheet attribute.
+If style sheet is completely omitted then input file is to be used as such as the configuration file without any transformation.
+The MIME type for XML files of Generic Configuration File ML is ``text/application+xml``.
+
+
+Full example files
+''''''''''''''''''
+
+Example Generic Configuration File ML file:
+
+.. literalinclude:: genconfml_example1.txt
+ :language: xml
+
+Example file that is passed to the included XSLT processor contains only selected data elements:
+
+.. literalinclude:: genconfml_example2.txt
+ :language: xml
+
+Example output file that is generated by XSLT processor:
+
+.. literalinclude:: genconfml_example3.txt
+ :language: xml
+
+The output file will be located under the output folder in a sub-folder determined based on the
+name and target attributes of the file element. E.g., in this case the output file's path is
+``output_dir/private/2000BEE5/CamcorderData.xml``.
+
+Notice that same result is obtained by having the following line in the GenConfML file:
+
+.. literalinclude:: genconfml_example5.txt
+ :language: xml
+
+XSD
+'''''''''
+
+Download: :download:`gcfml.xsd `
+
+
+FAQ
+'''''''''
+
+This will be updated based on the questions.
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/general.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/general.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,640 @@
+ImplML and plug-ins
+===================
+
+The `configuration project` concept contains an interface/implementation split
+by using the Configuration Markup Language (ConfML) to specify the interface for
+configurable entities in a project, and an arbitrary number of Implementation
+Markup Languages (ImplML) to specify the output generated based on the interface.
+
+ConE plug-ins supply the actual code-level implementations for the different
+implementation languages. This page describes common ImplML concepts.
+
+
+ImplML basics
+-------------
+
+All implementation languages are based on XML, and each separate
+Implementation Mark-up Language (ImplML) resides within a single
+XML namespace. The namespace of the ImplML must be defined in
+the file, or the implementation won't be recognized. For example,
+the following file is an example of CRML (Central Repository
+Mark-up Language):
+
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+Notice the use of the XML namespace ``xmlns="http://www.s60.com/xml/cenrep/1"``
+in the root element. This is what tells ConE that a CRML implementation should
+be read from this XML document's root element. Here there is only one implementation
+language used, and the extension of the file can reflect this (the extension is
+.crml in this case).
+
+However, the use of XML namespaces to differentiate implementation languages
+enables the mixing of multiple languages in a single implementation file.
+For example, the following file uses two implementation languages under common container,
+RuleML and ContentML:
+
+.. code-block:: xml
+
+
+
+
+
+ CustomSettings.StartupSoundFile.localPath configures StartupSettings.StartupSoundPath
+ = Startup.StartupSoundPath filenamejoin CustomSettings.StartupSoundFile.localPath
+
+
+
+
+
+
+
+
+
+
+The execution order of elements inside the container is the same as the order of definition.
+
+In this example, the RuleML section first sets the value of a ConfML setting,
+whose value is then used in the ContentML section to copy the file to the
+correct place.
+Notice how the XML namespaces are defined.
+
+ - The container is in http://www.symbianfoundation.org/xml/implml/1, the root element of implml namespace must always be container
+ - The ruleml is in http://www.s60.com/xml/ruleml/2
+ - The content is in xmlns="http://www.s60.com/xml/content/3"
+
+When reading the implementation file, ConE checks the document root and its namespace
+to find out from namespace to start parsing.
+
+.. _implml-file-extensions:
+
+File extensions
+^^^^^^^^^^^^^^^
+
+Implementations are read from files under layers' ``implml/`` directories
+inside the configuration project. The extensions of these files matter
+in whether implementations are attempted to be read from a file or
+not. The generic implementation file extension is ``implml``, but plug-ins
+may extend the list of supported file extensions. However, the extension
+does nothing more than specify whether the file is attempted to be parsed or
+not; no checking on the implementation types is done. This means that
+it is possible to create e.g. a CRML file with the extension ``templateml``,
+but of course this makes no sense and should be avoided.
+
+The extension checking mechanism is there in order to differentiate
+implementation files and any other related files, e.g. Python scripts
+used by RuleML implementations. This way, if an implementation file
+contains invalid XML data an error will be shown to the user, but a
+Python script (the reading of which as XML would invariably fail and
+produce an error) will simply be ignored.
+
+If you want to see what file extensions are supported, run to following
+command::
+
+ cone info --print-supported-impls
+
+This will print something like the following::
+
+ Running action info
+ Supported ImplML namespaces:
+ http://www.symbianfoundation.org/xml/implml/1
+ http://www.s60.com/xml/cenrep/1
+ http://www.s60.com/xml/content/1
+ http://www.s60.com/xml/content/2
+ http://www.s60.com/xml/convertprojectml/1
+ http://www.s60.com/xml/genconfml/1
+ http://www.s60.com/xml/imageml/1
+ http://www.s60.com/xml/ruleml/1
+ http://www.s60.com/xml/ruleml/2
+ http://www.s60.com/xml/templateml/1
+ http://www.s60.com/xml/thememl/1
+ http://www.symbianfoundation.org/xml/hcrml/1
+
+ Supported ImplML file extensions:
+ implml
+ content
+ contentml
+ crml
+ gcfml
+ convertprojectml
+ ruleml
+ imageml
+ thememl
+ templateml
+ hcrml
+
+Another way is to check the log file created when running ``cone generate``.
+It should contain a line like the following::
+
+ Supported implementation file extensions: ['templateml', 'ruleml', 'thememl', 'imageml', 'crml', 'content', 'contentml', 'convertprojectml', 'hcrml', 'gcfml', 'implml']
+
+**Guidelines for implementation file naming**
+
+- Use the corresponding file extension if the file contains only a
+ single implementation instance (e.g. ``.crml`` for a CRML implementation)
+- Otherwise use the generic ``implml`` extension with containers
+
+Implementation container nesting
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In example 1, implementations were defined under a single root container element. The container
+elements can be nested to form sub containers under the single implementation file.
+
+For example:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+ CustomSettings.StartupSoundFile.localPath configures
+ StartupSettings.StartupSoundPath = Startup.StartupSoundPath + "/" + CustomSettings.StartupSoundFile.localPath
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Here the root level container has two sub-containers, where the first sub-container
+is executed in "pre" phase ( definition) and the second in "normal" phase.
+
+.. _common-implml-namespace:
+
+Common ImplML namespace
+-----------------------
+
+Because there are common elements that are relevant for most, if not all, implementations,
+there is a common ImplML namespace (``http://www.symbianfoundation.org/xml/implml/1``)
+that contains these. The common elements can be defined by default in the container elements.
+The support for the plugin implementation support for common elements depends on the implementation
+of the plugin. So refer to the plugin specific documentation to what each plugins supports.
+
+.. _implml-common-elements:
+
+Elements
+^^^^^^^^
+
+The common ImplML elements are illustrated with the following UML class diagram:
+
+ .. image:: implml.jpg
+
+
+==================== ====================== ===============================================================================
+Element Cardinality Description
+==================== ====================== ===============================================================================
+container 1 .. * Defines a container for sub elements. For details see
+ :ref:`implml-common-container` .
+tempVariableSequence 0 .. * Defines a temporary sequence variable. For details see
+ :ref:`implml-common-temporary-variables`.
+tempVariable 0 .. * Defines a temporary variable. For details see
+ :ref:`implml-common-temporary-variables`.
+tag 0 .. * Defines an implementation tag. For details see
+ :ref:`implml-common-implementation-tags`.
+phase 0 .. 1 Defines a execution phase. For details see
+ :ref:`implml-common-invocation-phase` .
+==================== ====================== ===============================================================================
+
+.. _implml-common-container:
+
+Container element
+^^^^^^^^^^^^^^^^^
+
+The container element in the common namespace is like its name says a implementation
+that can contain other implementations. So in other words containers can contain
+other containers or actual implementations, like templateml, content, ruleml, etc.
+
+The key purpose of the containers is to offer a mechanism where one configuration
+implementation solution can be nicely wrapped to a single file. The whole solution might
+require generation of one or more output files, rules, content copying, executing system
+commands, etc. To resolve simple and more complex problems the containers offer a execution
+flow control, with phases, tags and conditions.
+
+Example with conditional container execution:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+In the above example the generation phase will check if the condition is evaluated as true before entering the container.
+The condition="${Feature1.Setting1}" refers to a Feature value inside the configuration, and value="true" requires
+that the value of that feature is True. So content copying of test/file1.txt to content/file1.txt is executed only when Setting1
+is set to True.
+
+.. _implml-common-invocation-phase:
+
+Invocation phase
+^^^^^^^^^^^^^^^^
+
+Containers and implementations may define the phase in which they are executed, which can be 'pre',
+'normal' or 'post'. The default phase is determined by the code-level implementation
+(usually the default phase is 'normal'), but this can be overridden for an
+implementation by using the ``phase`` element. The element contains a single mandatory
+attribute, ``name``, which defines the execution phase.
+
+When using containers in common implml files the ``phase`` of the implementation is always ignored.
+This enables overriding of the default ``phase`` of the implementations with the containers.
+
+Example with two implementation in post phase:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X.Y configures X.Z = X.Y
+
+
+
+
+Example with two containers in different phases:
+
+To run implementation in different phases you must define two separate containers
+that have a separate phase in them. In the below example the root level container
+is entered and executed in pre,post phase but the first sub-container only in
+pre phase and the second container in post phase.
+
+.. code-block:: xml
+
+
+
+
+
+
+ X.Y configures X.Z = X.Y
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.. _implml-common-implementation-tags:
+
+Implementation tags
+^^^^^^^^^^^^^^^^^^^
+
+A concept common to all implementations are implementation tags. These are simple
+name-value pairs that can be used as one way of filtering the implementations
+when generating. For example the tag ``target : core``, could be used to tag
+the particular implementation and, when generating, the same tag could be used to
+generate only implementations for the target *core*.
+
+Tags can be defined in implementations that support them or in containers that
+hold implementations. The overall tags of a container is a sum of all tags defined
+in its children (including sub-container and implementations)
+
+To generate only the implementations for the *core* target the following generation command could be used::
+
+ cone generate --impl-tag=target:core
+
+**Tag elements**
+
+Tag elements are simple XML elements defining name-value pairs.
+There can be multiple tags with the same name, in which case the resulting value
+for that tag will be a list of all the specified values. Examples:
+
+.. code-block:: xml
+
+
+
+
+
+
+Tags can also get their values from ConfML settings, which can be referenced in the usual way:
+
+.. code-block:: xml
+
+
+
+
+When tags are defined to the container it will basically affect on all its sub implementations.
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X.Y configures X.Z = X.Y
+
+
+
+In this case both the ContentML and RuleML sections would have the same tags.
+
+The tag elements can be defined also in some implementation namespaces directly under the root element. E.g. the content in the following
+content file would be copied to the output only for targets *core* and *rofs2*:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Filtering Based on Implementation Tags
+''''''''''''''''''''''''''''''''''''''
+
+This chapter explains how to create implementation tag specific implementation files.
+`cone_defaults.cfg` defines the default tags for plugins. If nothing is defined
+for a certain plugin type then plugin_tags variable is empty. Basically empty
+tag means that corresponding plugin participates only those generation where
+generation is not filtered by any implementation tag. If generation defines
+implementation tag filter then generation is done only for those plugins that
+match with the filter. If filter is not given filtering is not done and all
+plugins are participating in generation. In case of customization layer this
+would mean that uda content could end up to rofs3 section. Filtering is done
+only for normal and post phases, which means that you don't need to define
+any tag for ruleml files since they are ran in pre phase. Default value
+can be overridden in implementation file of the plugin like the following example
+shows.
+
+**Example 1:**
+
+Content plugin default value in cone_defaults.cfg is target:rofs3, which means
+that by default it participates in generations that doesn't define
+implementation tags or defines rofs3. However we want create content files that
+copies stuff to uda. It can be done by overriding tag in .content file by
+adding the following line there:
+
+::
+
+
+
+**Example 2:**
+
+commsdat.content doesn't contain any tag information and cccccc00.cre should
+go to rofs3 image. No actions needed because default value for content is rofs3.
+
+Current default values for plugins:
+
+::
+
+ CRML = 'core','rofs2','rofs3'
+ GCFML = 'core','rofs2','rofs3'
+ CONTENT = 'rofs3'
+ MAKEML = 'makefile'
+ RULEML = ''
+ IMAGEML = 'rofs3'
+ THEMEML = 'rofs3'
+
+Workflow for creating new implementation file:
+
+ .. image:: tag-fil.jpg
+
+
+
+.. _implml-common-temporary-variables:
+
+Temporary variables (generation-scope temporary ConfML features)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The common ImplML namespace also makes it possible to define temporary variables
+for e.g. passing information between implementations or specifying a constant in only
+one place. Unlike implementation tags, the temporary variables are not
+implementation-specific, but they are visible to all implementations, because they are
+normal ConfML settings. However, overwriting existing features in the
+configuration is prevented by raising an error when defining a feature that already exists.
+Therefore the names of used temporary variables should be chosen with care.
+
+Temporary variables can be defined as follows:
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Temporary variables only support the simplest ConfML setting types:
+
+- string
+- int
+- real
+- boolean
+
+**Usage example**
+
+In this example, we have the need to copy files from a number of different
+locations to the output directory based on arbitrary logic. To do this, we create
+a temporary sequence, populate it in a rule, and finally copy the files to
+the output. This way there is no need to define a custom ConfML setting in
+a separate file and include it in the project, so all implementation-specific
+concerns are on the implementation side and do not leak to the interface (ConfML).
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+ True configures FileCopyTemp.Files = {% get_file_list() %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.. _implml-common-setting-refs-override:
+
+Overriding setting references
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+During generation, implementation instance may be filtered based on the setting references
+they use. Normally the set of references should be correctly determined by the implementation
+instance itself, but if for some reason the references need to be overridden in the
+ImplML file, it is possible by using the common ``settingRefsOverride`` element.
+The element can be used in two ways:
+
+- It may contain a set of ``settingRef`` sub-elements defining the setting
+ references
+- It may contain a ``refsIrrelevant`` attribute that, if set to ``true``,
+ specifies that setting references are irrelevant for the implementation. In
+ this case the implementation will never be filtered out based on setting
+ references during generation.
+
+**Examples**
+
+.. code-block:: xml
+
+
+
+.. code-block:: xml
+
+
+
+
+
+
+
+.. _implml-common-setting-output-dir-override:
+
+Overriding output directory parts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The final output directory for implementation output is consists of three parts:
+
+- *Output root*, speficied from the command in the ``generate`` action
+- *Output sub-dir*, specified in a setting file (e.g. ``content/`` for CRML in
+ iMaker variant content output settings file)
+- *Plug-in output*, specified in a setting file (e.g. ``private/10202BE9`` for CRML)
+- *Output file name*, specified in the implementation file in some way, may also
+ contain some intermediary directories before the actual file name
+ (e.g. ``12345678.txt`` for a CRML file with repository UID 0x12345678)
+
+Of these, the two first may be overridden in the implementation file using
+the common ImplML elements ``outputRootDir`` and ``outputSubDir``. These elements
+may contain a single ``value`` attribute containing the directory name.
+
+**Examples**
+
+.. code-block:: xml
+
+
+
+
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In the above example the content is copied to \epoc32\data\widgets\some_dir\text.wgz.
+
+
+.. rubric:: Footnotes
+
+.. [#multi-content-note] In this case the run-time behavior would still be same; ContentML
+ allows multiple ``output`` elements. However, this might not be the case for all
+ implementation languages.
+
+.. [#legacy-implml-root-name-note] The specifications for the legacy implementation
+ languages CRML and GenConfML do give the root element names, and say that each
+ implementation must be in its own crml/gcfml file.
+ It is recommended to stick to this convention for these two implementation languages
+ also in the future. Indeed, using them in a multi-implementation file has not been
+ tested and may not even work correctly.
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/hcrml-plugin/hcr_dat.png
Binary file configurationengine/doc/plugins/hcrml-plugin/hcr_dat.png has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/hcrml-plugin/hcr_diagram.uml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/hcrml-plugin/hcr_diagram.uml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1039 @@
+
+
+
+
+
+
+
+
+
+
+Untitled
+1
+
+Model1
+KP8MW2AJ4EaQPbS2U99tdgAA
+1
+
+hcrml_elements
+PGTjH/H2T0Cw+snKUpOfhAAA
+
+es0kksaNwU6dH75+6sWUBgAA
+12
+
+clMaroon
+$00B9FFFF
+188
+56
+67
+36
+True
+1J3CkvMFlEyFBEHrsOJGtAAA
+
+
+1
+
+
+<<hcrml>>
+
+
+False
+
+
+
+False
+1J3CkvMFlEyFBEHrsOJGtAAA
+
+
+False
+1J3CkvMFlEyFBEHrsOJGtAAA
+
+
+False
+1J3CkvMFlEyFBEHrsOJGtAAA
+
+
+
+clMaroon
+$00B9FFFF
+99
+148
+62
+85
+True
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+1
+output
+
+
+False
+
+
+False
+
+
+
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+False
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+False
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+
+clMaroon
+$00B9FFFF
+278
+167
+61
+46
+True
+ZSLRiuLfmkWNzAHtjG7MxAAA
+
+
+1
+category
+
+
+False
+
+
+False
+
+
+
+ZSLRiuLfmkWNzAHtjG7MxAAA
+
+
+False
+ZSLRiuLfmkWNzAHtjG7MxAAA
+
+
+False
+ZSLRiuLfmkWNzAHtjG7MxAAA
+
+
+
+clMaroon
+$00B9FFFF
+278
+252
+61
+98
+True
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+1
+setting
+
+
+False
+
+
+False
+
+
+
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+False
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+False
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+
+clMaroon
+$00B9FFFF
+272
+400
+73
+72
+True
+g5HW/StTxEO8a2R31wFJGAAA
+
+
+1
+flags
+
+
+False
+
+
+False
+
+
+
+g5HW/StTxEO8a2R31wFJGAAA
+
+
+False
+g5HW/StTxEO8a2R31wFJGAAA
+
+
+False
+g5HW/StTxEO8a2R31wFJGAAA
+
+
+
+clMaroon
+$00B9FFFF
+105
+292
+50
+46
+True
+T5a2qChBf0emwtAyXmuJdwAA
+
+
+1
+include
+
+
+False
+
+
+False
+
+
+
+T5a2qChBf0emwtAyXmuJdwAA
+
+
+False
+T5a2qChBf0emwtAyXmuJdwAA
+
+
+False
+T5a2qChBf0emwtAyXmuJdwAA
+
+
+
+clMaroon
+$00B9FFFF
+160,151;207,91
+SXBvv/yrwESZkBHGi7wOYQAA
+USbBAMvkdU+zaV4XNH48xwAA
+90+0XkM4FEWSvc0hDcS8hQAA
+
+False
+1.5707963267949
+15
+SXBvv/yrwESZkBHGi7wOYQAA
+
+
+False
+1.5707963267949
+30
+SXBvv/yrwESZkBHGi7wOYQAA
+
+
+False
+-1.5707963267949
+15
+SXBvv/yrwESZkBHGi7wOYQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+nOgz2ElH10298hw2CJeauwAA
+
+
+False
+0.523598775598299
+30
+epTail
+5yRfwhL4YUCn3dlCCSdDoAAA
+
+
+False
+0.523598775598299
+25
+epHead
+nOgz2ElH10298hw2CJeauwAA
+
+
+-0.523598775598299
+25
+epTail
+0..1
+5yRfwhL4YUCn3dlCCSdDoAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+nOgz2ElH10298hw2CJeauwAA
+
+
+False
+0.785398163397448
+40
+epTail
+5yRfwhL4YUCn3dlCCSdDoAAA
+
+
+False
+-1000
+-1000
+50
+8
+nOgz2ElH10298hw2CJeauwAA
+
+
+False
+-1000
+-1000
+50
+8
+5yRfwhL4YUCn3dlCCSdDoAAA
+
+
+
+clMaroon
+$00B9FFFF
+292,167;235,91
+w6C/walGe0evZIkpW1v9cQAA
+USbBAMvkdU+zaV4XNH48xwAA
+/8ebn4fbc0GwVvHGdHUs7wAA
+
+False
+1.5707963267949
+15
+w6C/walGe0evZIkpW1v9cQAA
+
+
+False
+1.5707963267949
+30
+w6C/walGe0evZIkpW1v9cQAA
+
+
+False
+-1.5707963267949
+15
+w6C/walGe0evZIkpW1v9cQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+Q4xX5lDyPkS2RIO7Hfe35gAA
+
+
+False
+0.523598775598299
+30
+epTail
+E42e6HOOBUWXlVVzGtxSDQAA
+
+
+False
+0.523598775598299
+25
+epHead
+Q4xX5lDyPkS2RIO7Hfe35gAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+E42e6HOOBUWXlVVzGtxSDQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+Q4xX5lDyPkS2RIO7Hfe35gAA
+
+
+False
+0.785398163397448
+40
+epTail
+E42e6HOOBUWXlVVzGtxSDQAA
+
+
+False
+-1000
+-1000
+50
+8
+Q4xX5lDyPkS2RIO7Hfe35gAA
+
+
+False
+-1000
+-1000
+50
+8
+E42e6HOOBUWXlVVzGtxSDQAA
+
+
+
+clMaroon
+$00B9FFFF
+129,292;129,232
+p1QIDju8c06lOzVWjm5bfgAA
+90+0XkM4FEWSvc0hDcS8hQAA
+h7HTNndSGker+jhbQvalSgAA
+
+False
+1.5707963267949
+15
+p1QIDju8c06lOzVWjm5bfgAA
+
+
+False
+1.5707963267949
+30
+p1QIDju8c06lOzVWjm5bfgAA
+
+
+False
+-1.5707963267949
+15
+p1QIDju8c06lOzVWjm5bfgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+bK2IMyA5QUiAj7nAMWOHrgAA
+
+
+False
+0.523598775598299
+30
+epTail
+qpqQ4elhKUmjonZgVOvpOAAA
+
+
+False
+0.523598775598299
+25
+epHead
+bK2IMyA5QUiAj7nAMWOHrgAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+qpqQ4elhKUmjonZgVOvpOAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+bK2IMyA5QUiAj7nAMWOHrgAA
+
+
+False
+0.785398163397448
+40
+epTail
+qpqQ4elhKUmjonZgVOvpOAAA
+
+
+False
+-1000
+-1000
+50
+8
+bK2IMyA5QUiAj7nAMWOHrgAA
+
+
+False
+-1000
+-1000
+50
+8
+qpqQ4elhKUmjonZgVOvpOAAA
+
+
+
+clMaroon
+$00B9FFFF
+308,252;308,212
+sKOn/cx030SedAQVnUh6ZQAA
+/8ebn4fbc0GwVvHGdHUs7wAA
+EmtFrUjEtUCaTo178nzlXwAA
+
+False
+1.5707963267949
+15
+sKOn/cx030SedAQVnUh6ZQAA
+
+
+False
+1.5707963267949
+30
+sKOn/cx030SedAQVnUh6ZQAA
+
+
+False
+-1.5707963267949
+15
+sKOn/cx030SedAQVnUh6ZQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+iimfnoFJmEK0X5e0JaQTPgAA
+
+
+False
+0.523598775598299
+30
+epTail
+te1qdkzq8EaWy8tgF/Vv2AAA
+
+
+0.679413788174143
+33.4215499341368
+epHead
+0..*
+iimfnoFJmEK0X5e0JaQTPgAA
+
+
+False
+-0.523598775598299
+25
+epTail
+te1qdkzq8EaWy8tgF/Vv2AAA
+
+
+False
+-0.785398163397448
+40
+epHead
+iimfnoFJmEK0X5e0JaQTPgAA
+
+
+False
+0.785398163397448
+40
+epTail
+te1qdkzq8EaWy8tgF/Vv2AAA
+
+
+False
+-1000
+-1000
+50
+8
+iimfnoFJmEK0X5e0JaQTPgAA
+
+
+False
+-1000
+-1000
+50
+8
+te1qdkzq8EaWy8tgF/Vv2AAA
+
+
+
+clMaroon
+$00B9FFFF
+308,400;308,349
+H9608kb890mvhOSgz8UP+AAA
+EmtFrUjEtUCaTo178nzlXwAA
+kJLxcue6x0u84gD7oW/MwAAA
+
+False
+1.5707963267949
+15
+H9608kb890mvhOSgz8UP+AAA
+
+
+False
+1.5707963267949
+30
+H9608kb890mvhOSgz8UP+AAA
+
+
+False
+-1.5707963267949
+15
+H9608kb890mvhOSgz8UP+AAA
+
+
+False
+-0.523598775598299
+30
+epHead
+CFpTL7Di+0aVEPq/ybpqUwAA
+
+
+False
+0.523598775598299
+30
+epTail
+EE6T7JCajU2jejPWIkBaXQAA
+
+
+False
+0.523598775598299
+25
+epHead
+CFpTL7Di+0aVEPq/ybpqUwAA
+
+
+-0.881872031161297
+22.0227155455452
+epTail
+0..*
+EE6T7JCajU2jejPWIkBaXQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+CFpTL7Di+0aVEPq/ybpqUwAA
+
+
+False
+0.785398163397448
+40
+epTail
+EE6T7JCajU2jejPWIkBaXQAA
+
+
+False
+-1000
+-1000
+50
+8
+CFpTL7Di+0aVEPq/ybpqUwAA
+
+
+False
+-1000
+-1000
+50
+8
+EE6T7JCajU2jejPWIkBaXQAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+278,190;160,190
+etnO7NCQUkemhFwPoVn7cwAA
+90+0XkM4FEWSvc0hDcS8hQAA
+/8ebn4fbc0GwVvHGdHUs7wAA
+
+False
+1.5707963267949
+15
+etnO7NCQUkemhFwPoVn7cwAA
+
+
+False
+1.5707963267949
+30
+etnO7NCQUkemhFwPoVn7cwAA
+
+
+False
+-1.5707963267949
+15
+etnO7NCQUkemhFwPoVn7cwAA
+
+
+False
+-0.523598775598299
+30
+epHead
++65Z0BKNqkOuFO68bobBKAAA
+
+
+False
+0.523598775598299
+30
+epTail
+OAWY5ng5Ckemq84Y7VjRLgAA
+
+
+False
+0.523598775598299
+25
+epHead
++65Z0BKNqkOuFO68bobBKAAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+OAWY5ng5Ckemq84Y7VjRLgAA
+
+
+False
+-0.785398163397448
+40
+epHead
++65Z0BKNqkOuFO68bobBKAAA
+
+
+False
+0.785398163397448
+40
+epTail
+OAWY5ng5Ckemq84Y7VjRLgAA
+
+
+False
+-1000
+-1000
+50
+8
++65Z0BKNqkOuFO68bobBKAAA
+
+
+False
+-1000
+-1000
+50
+8
+OAWY5ng5Ckemq84Y7VjRLgAA
+
+
+
+
+12
+
+hcrml
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+USbBAMvkdU+zaV4XNH48xwAA
+6EX7k5+unEGGf705CHb3BwAA
+s6/9I0lCiEqddgKhuVDbuwAA
+qhebg4kZ1kW9T/F4Ol2erwAA
+2
+nOgz2ElH10298hw2CJeauwAA
+Q4xX5lDyPkS2RIO7Hfe35gAA
+
+
+output
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+90+0XkM4FEWSvc0hDcS8hQAA
+GP/d7xdnJk29AbjUbCDFzgAA
+4jfn5jjHsE6tzHK1czetGgAA
+NUBzdiG7Jk2e94HxWeOYOwAA
+3
+5yRfwhL4YUCn3dlCCSdDoAAA
+bK2IMyA5QUiAj7nAMWOHrgAA
++65Z0BKNqkOuFO68bobBKAAA
+4
+
+file
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+type
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+version
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+readOnly
+/Dzo/UB98UO2HlqvzEUOtQAA
+
+
+
+category
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+/8ebn4fbc0GwVvHGdHUs7wAA
+2ffSCszEikagMBCQm0qYPAAA
+AeGaTz/9JUy2DFPWy9yj6AAA
+d4+BmgEiIkqS0gDU+hg7UgAA
+3
+E42e6HOOBUWXlVVzGtxSDQAA
+iimfnoFJmEK0X5e0JaQTPgAA
+OAWY5ng5Ckemq84Y7VjRLgAA
+1
+
+uid
+ZSLRiuLfmkWNzAHtjG7MxAAA
+
+
+
+setting
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+EmtFrUjEtUCaTo178nzlXwAA
+2P9sUmT3gEOuT3mIAeznywAA
+TGENQxZ86k+pAN3oz8w/rAAA
+buuTrQKu/UOYDYXIN4X2jwAA
+2
+te1qdkzq8EaWy8tgF/Vv2AAA
+CFpTL7Di+0aVEPq/ybpqUwAA
+5
+
+ref
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+name
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+id
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+type
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+comment
+eRTiGhfJ90ONKB7vYPd9OwAA
+
+
+
+flags
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+kJLxcue6x0u84gD7oW/MwAAA
+uSlR5AWRnEOhZNkhY8dafgAA
+P+88A43vq0OF3w/jVw50nAAA
+yjdf5r67aE+HDjD/99Og4AAA
+1
+EE6T7JCajU2jejPWIkBaXQAA
+3
+
+uninitialized
+g5HW/StTxEO8a2R31wFJGAAA
+
+
+modifiable
+g5HW/StTxEO8a2R31wFJGAAA
+
+
+persistent
+g5HW/StTxEO8a2R31wFJGAAA
+
+
+
+include
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+h7HTNndSGker+jhbQvalSgAA
+EV0WFYrJEEOSmHY0hlSIpQAA
+sd84VZqmaEOhviGYnjq8AAAA
+mwZwjK21y0u7OHSaF+c+qQAA
+1
+qpqQ4elhKUmjonZgVOvpOAAA
+1
+
+ref
+T5a2qChBf0emwtAyXmuJdwAA
+
+
+
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+6KT2d7NjBE6cL8ksI7FBIAAA
+q47/cW8GHU6sL3QObV02ygAA
+o2IR0kGtGEeYALto8VPdSwAA
+Xy2KZjE3P0eZJ9ZkCcvpnAAA
+2
+
+0..1
+SXBvv/yrwESZkBHGi7wOYQAA
+/Dzo/UB98UO2HlqvzEUOtQAA
+4
+A8WJJ9PbGEuWaqp9RZ3vlQAA
+K2npH6yJiEG8732+l/siCgAA
+4ziEVm2OBUamCPHrTWtb0gAA
+nu7xBpS2YkCpS8Ho0JJhqQAA
+
+
+akComposite
+SXBvv/yrwESZkBHGi7wOYQAA
+1J3CkvMFlEyFBEHrsOJGtAAA
+4
+Op0NtPyglkGxvO8nW3Ck2QAA
+oDRtl3JnPUyJFZvqmcVLdQAA
+C05lqqmfeEGXKE0tKUoEKgAA
+6eztFek9L0yZHw9SL/eMBgAA
+
+
+
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+4/wEq0iJ00W3+a92k6yk6QAA
+U2d8ZEjYI0mtWpl/kDdHjgAA
+m+nJcaYDKUKQGdsfXu0KuwAA
+PE2J8IpmaUuKjdRfpaLoawAA
+2
+
+0..*
+w6C/walGe0evZIkpW1v9cQAA
+ZSLRiuLfmkWNzAHtjG7MxAAA
+4
+N+hayhtST0qI8uEhO6XFGgAA
+S4XDPyYtaEG4QZ+ZoihgKgAA
+f8buhcQv/U+kGT9yVSZBagAA
+SIE3N2FHsUWwVw/MdrR6aAAA
+
+
+akComposite
+w6C/walGe0evZIkpW1v9cQAA
+1J3CkvMFlEyFBEHrsOJGtAAA
+4
+1tft9JkEy0+mAJZ7hqUohwAA
+R32nuYG0mkyW9syy+rHL/gAA
+reF5ps+9rU2KZI8cuoGIVwAA
+jeC/QuvS0ky7Dr2MVtpGjQAA
+
+
+
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+4ph9TrZl1UOUAMwM2w+PQgAA
+/+CXrfYl00GP4xQhlXDQugAA
+SFQ2ztszTk6xmp20h/C0XAAA
+9/DF3KExE0Cvi6K92bbugAAA
+2
+
+0..*
+p1QIDju8c06lOzVWjm5bfgAA
+T5a2qChBf0emwtAyXmuJdwAA
+4
+VHoxIzNu1kiZKQv8M5rM8AAA
+Jmq3h0Qv2ESaSglLIn1ZzAAA
+Bpm+slTtNUWuPmD4CzZrZwAA
+TUY65taZe0C7H6h5wY7JTgAA
+
+
+akComposite
+p1QIDju8c06lOzVWjm5bfgAA
+/Dzo/UB98UO2HlqvzEUOtQAA
+4
+pzgec13dM0aManQpyaPbYAAA
+Ygz8uaSzNES0KNwJEUoLNQAA
+ptbfXT/JNEqotOlgcK3g+gAA
+DAYp+Nrbi0iQhsaKtsRmPgAA
+
+
+
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+xF2J+LXJxUCn2T/vd6gnygAA
+4s4niPVs0kymeaRU0Z4f3AAA
+d8tiCB7gD0+6euJHHzdF8gAA
+0+IcA7WboUSsBfNeT/hgrgAA
+2
+
+sKOn/cx030SedAQVnUh6ZQAA
+eRTiGhfJ90ONKB7vYPd9OwAA
+4
+crH275uvpkKQvB69KBfwQwAA
+7rcE9sJNZkCHL7t2vW5LugAA
+cz/yFSW91EarUx7DFJJhXwAA
+Z6FjsUP0Tkm6+0ucrbS00AAA
+
+
+akComposite
+0..*
+sKOn/cx030SedAQVnUh6ZQAA
+ZSLRiuLfmkWNzAHtjG7MxAAA
+4
+vJ8TmV4RzUS6lPNccLoLwAAA
+Hz5+T85OEUSkzudjIKXl9QAA
+3SK0qlHt7UCa31x5EFGX4wAA
+ylC2fZK2pkW8U+HL8oa1kAAA
+
+
+
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+a4h7IShwykSGqhFNQUaeiAAA
+MgNgVnAnBUeyOuvRRiTRBAAA
++r03o1h/akCjV7eC+sRXGAAA
+NPVXYtyKuUueWkWtqHahxwAA
+2
+
+0..*
+H9608kb890mvhOSgz8UP+AAA
+g5HW/StTxEO8a2R31wFJGAAA
+4
+w1ihFhlJvkSygZ+AVGmD8wAA
+PposSZlJv0KmPtS2V/ZAZAAA
+RwVm5wKIJ0Gyp/gCO/owZwAA
+qVMA85GvhUanfQJOUbqSzwAA
+
+
+akComposite
+H9608kb890mvhOSgz8UP+AAA
+eRTiGhfJ90ONKB7vYPd9OwAA
+4
+lUvGN2bPtku5fTy4mWI/MgAA
+qyoYegWpvk+nKh5q+Rdw0gAA
+XvPW20TgIEeb7uERIeM/hwAA
+ByMgAv0IokS9cpUnyY8n/wAA
+
+
+
+PGTjH/H2T0Cw+snKUpOfhAAA
+4
+D+872E2dEUuYXZNx4hB+RQAA
+A+B2S73g4EyTWLXAwSc1IAAA
+/NN27mUSEkiUo9RRoAPJWgAA
+C1zGLW2Xy0uDdHWNRPE4tQAA
+2
+
+0..*
+etnO7NCQUkemhFwPoVn7cwAA
+ZSLRiuLfmkWNzAHtjG7MxAAA
+4
+3+FXNI5eo0GZM264rgzKSQAA
+mySvGw0ty06UERO75RdF6gAA
+YW2CkNerFU2X9f8CGvTR0AAA
+at49h/9gn02OWRaVDd+O2QAA
+
+
+akComposite
+etnO7NCQUkemhFwPoVn7cwAA
+/Dzo/UB98UO2HlqvzEUOtQAA
+4
+KMvckZhjgECMR9D7d9l9wwAA
+26ySfJL8u0+rybTkSbzRiwAA
+ITokhtYjWE+aUg0r3N+TmgAA
+W5Oa53rFmUO8Hsi4pVbfuAAA
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/hcrml-plugin/hcrml-plugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/hcrml-plugin/hcrml-plugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,351 @@
+User guide for HCR Plugin usage in ConE
+=======================================
+
+Introduction
+------------
+This page describes how to use ConE HCR plug-in (for Hardware configuration repository).
+The plug-in defines the HCRML Implementation Markup Language, whose purpose is to provide
+the means for creating bindings between ConfML settings and Hardware Configuration Repository
+keys, and generating hcr.dat and C++ header files based on these bindings.
+
+XML namespace and file extension
+--------------------------------
+
+- Namespace: ``http://www.symbianfoundation.org/xml/hcrml/1``
+- File extension: ``hcrml``
+
+HCRML elements
+--------------
+
+The HCRML model is drawn out as a UML model in below picture.
+
+ .. image:: hcrml_elements.jpg
+
+category
+^^^^^^^^
+
+The category represents the same concept as a category in the HCR specification, which must have a name and UID.
+The category element can exist directly under the HCRML root element or an output element.
+
+**Attributes**
+
+ * *name* - C++ variable name for the category UID in the generated header file
+ * *uid* - UID of the category, must be unique in the repository
+
+**Example**
+
+.. code-block:: xml
+
+
+
+
+setting
+^^^^^^^
+
+The setting is a sub element of category, it can only exist inside a category. The setting can have the following
+attributes:
+
+**Attributes**
+
+ * *name* - C++ variable name for the setting UID in the generated header file
+ * *id* - UID of the setting, must be unique under a certain category
+ * *type* - Type of the setting (can be one of setting value types, see next section)
+ * *comment* - Single-line comment for the setting (visible in the generated header file)
+
+
+**Setting value type definitions**
+
+The HCRML value type definitions are derived from repository definitions. So the value type is the
+same in HCRML, where the prefix EType has been removed and the entry is in lower case.
+
+
+ ============== ==============
+ HCRML type HCR type
+ ============== ==============
+ int32 ETypeInt32
+ int16 ETypeInt16
+ int8 ETypeInt8
+ bool ETypeBool
+ uint32 ETypeUInt32
+ uint16 ETypeUInt16
+ uint8 ETypeUInt8
+ linaddr ETypeLinAddr
+ bindata ETypeBinData
+ text8 ETypeText8
+ arrayint32 ETypeArrayInt32
+ arrayuint32 ETypeArrayUInt32
+ int64 ETypeInt64
+ uint64 ETypeUInt64
+ ============== ==============
+
+Note:
+Data for the type ``text8`` is encoded in UTF-8. This means that pure ASCII text will work
+correctly without any further processing, and if any characters outside the ASCII range
+are expected to be in the text, the C++ implementation will need to take the encoding into
+account.
+
+**Supported ConfML setting types for HCRML types**
+
++------------------+------------------------------------------------------------------+
+| HCRML type | ConfML setting type |
++==================+==================================================================+
+| int8, int16, | int |
+| int32, int64, | |
+| uint8, uint16, | |
+| uint32, uint64, | |
+| linaddr | |
++------------------+------------------------------------------------------------------+
+| bool | boolean, int |
++------------------+------------------------------------------------------------------+
+| arrayint32, | Sequence with an int sub-setting |
+| arrayuint32 | |
++------------------+------------------------------------------------------------------+
+| text8 | string |
++------------------+------------------------------------------------------------------+
+| bindata | string with a hexadecimal value, whitespace ignored |
+| | (e.g. ``ABCDEF 1234 5678``) |
++------------------+------------------------------------------------------------------+
+
+**Examples**
+
+.. code-block:: xml
+
+
+
+
+
+flags
+^^^^^
+
+Flags element is a subelement of setting that can be used to define bit flags to a setting.
+
+**Attributes**
+
+Each flag attribute can have values 0,1, default value is 0.
+
+ * *uninitialised*
+ * *modifiable*
+ * *persistent*
+
+
+**Examples**
+
+.. code-block:: xml
+
+
+
+
+output
+^^^^^^
+
+Output element is a subelement of the root HCRML element used define output file generation. The output element
+should include a set of category and setting definitions that are included in the output file. The output section can
+also include other HCRML files to include category/setting definitions to it.
+
+If the included HCRML files contain output sections of their own, the generation is supposed the generate
+only the topmost output element. So any included output element is simply ignored.
+
+**Attributes**
+
+ * *file* - The output filename to be generated)
+ * *type* - The output file type, which can be one of [header|hcr]
+ * *version* - For hcr.dat, the HCR version number
+ * *readonly* - For hcr.dat, the read-only bit
+
+
+**Examples**
+
+.. code-block:: xml
+
+
+
+
+
+
+include
+^^^^^^^
+Include element can be used to include content of other HCRML files. The purpose is mainly to allow
+inclusion of categories and settings inside the output section. It allows wildcards to enable inclusion of
+multiple HCRML files with single line, or the inclusion of all existing HCRML files.
+
+**Attributes**
+
+ * *ref* - The pattern for including files
+
+**Examples**
+
+.. code-block:: xml
+
+
+
+
+
+Creating an HCRML configuration file
+------------------------------------
+
+The HCRML format is designed for two purposes. To allow definition of components specific binding
+between confml settings and Hardware configuration repository keys and to create/generate a C++ type
+header file from HCR key definition file. Secondly to allow creation/generation of Hardware
+configuration repository output file from multiple developer/component specific HCRML files.
+
+The normal lifecycle of these implementation files is described in below.
+
+ 1. Create/define the components configuration interface with confml
+ 2. Create/define the needed hcr keys and the binding between confml features.
+ 3. Generate the C++ header for the component from the configuration project
+
+ * e.g. ``cone generate`` (in the conf folder)
+
+ 4. Export/merge the component configuration as part of global configuration
+
+ * e.g. ``cone merge -r . -p /epoc32/rom/config_project/hcr`` (in the conf folder)
+
+ .. image:: hcrml_developer_project.png
+
+ 5. Define hcrml for hcr.dat generation. (Should be eventually in the same hcr layer inside the configuration project)
+ 6. Generate the HCR.DAT
+
+ * e.g. ``cone generate -p /epoc32/rom/config_project/hcr``
+
+ .. image:: hcrml_global_project.png
+
+Examples
+--------
+
+**HCRML file example**
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+**Explanation**
+
+The above HCRML file defines three settings's under category KCatGPIO, which has the UID 0x10001234. Each
+setting must have a unique ID inside the category. And each setting must define ref that points to a confml
+setting. The data value of that particular key is fetched from that confml reference. The name element
+in the category and settings can be used to generate the C header file from the HCRML.
+
+A output element encapsulates the setting definitions in this file. It is not necessary, but it enables
+that example.h header file can be generated from this component specific HCRML file.
+
+**HCR repository file example**
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+**Explanation**
+
+The above HCRML entry would define a HCR binary output file HCR.DAT with version 1 and readonly bit true.
+The file generation will try to include all .hcrml ending files from the configuration project.
+The include statement will just look for any matching file and include its content inside this file. If the
+included hcrml files include an output section, they are simple ingored and only the topmost output
+file will be generated.
+
+The output file section will in the end contain all categories and keys of all HCRML files.
+These files would normally be the files which are exported to the configuration project from several
+component configurations.
+
+Downloadable example
+--------------------
+
+Download: :download:`hcrml_example.zip`
+
+This example contains a mock developer project like shown earlier. It has
+a ``conf/`` directory containing the ConfML and HCRML files, and (empty) ``inc/``,
+``src/`` and ``group/`` directories. The important part is the ``conf/`` directory, which
+contains the following files:
+
+- ``confml/hcr_component1.confml`` - ConfML interface for the HCR settings
+- ``implml/component1.hcrml`` - HCRML file defining the binding between the ConfML settings and the HCR settings
+- ``implml/hcr_dat.hcrml`` - HCRML file for generating ``hcr.dat``
+- ``implml/hcr_keys.hcrml`` - HCRML file for generating ``hcr_keys.h``
+- ``root.confml`` - Needed for generation to work; contains a link to ``confml/hcr_component1.confml``
+
+To generate, cd to ``component1/conf/`` and run::
+
+ cone generate
+
+This will generate an ``output/`` directory with the files ``hcr.dat`` and ``hcr_keys.h``.
+
+Linking between ConfML/HCRML/output
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Here the linking between ConfML/HCRML/output is shown using the binary data
+setting. Irrelevant parts of the files are omitted for clarity.
+
+**ConfML:**
+
+.. code-block:: xml
+
+
+ ...
+
+ ...
+
+ ...
+
+
+ ...
+ 00112233 DEADBEEF CAFE 50
+ ...
+
+
+
+**HCRML:**
+
+.. code-block:: xml
+
+
+ ...
+
+ ...
+
+
+**Output - hcr.dat:**
+
+.. image:: hcr_dat.png
+
+
+**Output - hcr_keys.h:**
+
+.. code-block:: c++
+
+ #ifndef HCR_KEYS_H
+ #define HCR_KEYS_H
+
+ #include
+
+ const HCR::TCategoryUid KHcrComponent1 = 0x00000001;
+
+ ...
+
+ // Binary data setting
+ const HCR::TElementId KBinDataSetting = 0x00000005;
+
+ #endif
+
+XSD
+---
+
+Download: :download:`hcrml.xsd `
+
+FAQ
+---
+
+This will be updated based on the questions.
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/hcrml-plugin/hcrml_developer_project.png
Binary file configurationengine/doc/plugins/hcrml-plugin/hcrml_developer_project.png has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/hcrml-plugin/hcrml_elements.jpg
Binary file configurationengine/doc/plugins/hcrml-plugin/hcrml_elements.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/hcrml-plugin/hcrml_example.zip
Binary file configurationengine/doc/plugins/hcrml-plugin/hcrml_example.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/hcrml-plugin/hcrml_global_project.png
Binary file configurationengine/doc/plugins/hcrml-plugin/hcrml_global_project.png has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/implml.jpg
Binary file configurationengine/doc/plugins/implml.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/index.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/index.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,44 @@
+ConE plug-ins
+=============
+
+General
+-------
+
+.. toctree::
+ :maxdepth: 3
+
+ general
+ plugin-dir-structure
+
+Existing ConE plug-ins
+----------------------
+
+**Common plugins:**
+
+.. toctree::
+ :maxdepth: 1
+
+ contentml-plugin/content
+ commandml-plugin/commandml
+ ruleml-plugin/ruleplugin
+ templateml-plugin/templatemlplugin
+
+
+**Symbian specific plug-ins:**
+
+.. toctree::
+ :maxdepth: 1
+
+ crml-plugin/crmlplugin
+ genconfml-plugin/genconfmlplugin
+ hcrml-plugin/hcrml-plugin
+ convertprojectplugin
+ thememl-plugin/themelplugin
+
+ConE plug-in development
+------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ dev-plugin/index
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/plugin-dir-structure.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/plugin-dir-structure.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,66 @@
+Plug-in directory structure
+===========================
+
+ConE plug-ins are divided into plug-in "packages", which enables a ConE
+distribution to be built with a specific set of installed plug-ins. There is a ``common``
+package that contains the default plug-ins that are always present in a ConE installation,
+and any other plug-in package provides extra plug-ins in addition to these.
+
+For example, one might build a 'vanilla' ConE distribution which contains only the
+core ConE components and common plug-ins, or a 'symbian' distribution which contains
+those as well as all Symbian-specific plug-ins.
+
+The plug-in packages are simply sub-directories of ``source/plugins``. For example, the
+following shows the current plug-in packages:
+
+ .. image:: plugins-dir.png
+
+As can be seen, there are three plug-in packages (``common``, ``example`` and ``symbian``)
+and several utility Python files.
+
+Package directory structure
+---------------------------
+
+Each plug-in package contains the sources of all plug-ins, an optional integration test set,
+and a Python script to run all test cases related to the plug-in package. For example, the
+following shows the contents of the ``common`` plug-in package:
+
+ .. image:: plugins-common-dir.png
+
+The naming of the sub-directories is important:
+
+- Directories with a name of the form ``Cone*Plugin`` are considered to be plug-in sources
+- If a directory with the name ``integration-test`` exists, it is expected to contain a
+ ``runtests.py`` file that runs the integration tests
+
+Plug-in source directory structure
+----------------------------------
+
+A plug-in source directory is expected to contain two things:
+
+- A single Python module that contains the plug-in sources
+- ``setup.py`` for packaging the plug-in into an egg (``setup.cfg`` and ``makefile`` are related to this)
+
+The following shows the contents of the command plug-in directory in the common package:
+
+ .. image:: plugins-common-commandplugin-dir.png
+
+For an example with more complete descriptions see
+:ref:`here `.
+
+Integration test directory structure
+------------------------------------
+
+In addition to a collection of plug-in sources a plug-in package directory may contain an
+``integration-test`` directory. This directory is supposed to contain integration tests
+for the plug-ins by running actions (e.g. generate) using the ConE CLI to test that the plug-ins
+work correctly from the topmost level.
+
+File naming matters here too:
+
+- Files of the form ``unittest_*.py`` are expected to contain the test cases
+- If a file named ``export_standalone.py`` exists, it is expected to contain a function that
+ exports any needed extra data when exporting the integration tests into a standalone test set.
+
+For an example with more complete descriptions see
+:ref:`here
+
+
+
+
+
+UMLStandard
+
+
+
+
+Untitled
+5
+
+Use Case Model
+UMLStandard
+useCaseModel
+7KBTiD3bXUedYhpH6MqM/gAA
+1
+
+Main
+WkThTKLQekywYrWHRVBmjgAA
+
+shed/+eO2EaotQS3PS0jUgAA
+
+
+
+
+Analysis Model
+UMLStandard
+analysisModel
+7KBTiD3bXUedYhpH6MqM/gAA
+1
+
+Main
+True
+RobustnessDiagram
+sJP9kFOv5Ua3TZXoe2x73AAA
+
+TnUGBj9QCEm+WrEkTnMNfgAA
+
+
+
+
+Design Model
+UMLStandard
+designModel
+7KBTiD3bXUedYhpH6MqM/gAA
+1
+
+Main
+True
+8/PDgZYaSkyhn9djg2OS7wAA
+
+KeZ6ndZ6HEapeG6MtHJMZgAA
+1
+
+clMaroon
+$00B9FFFF
+416
+124
+86
+45
+sdkIcon
+IONricIIR0WGo59WsXpFtgAA
+
+
+1
+implbase
+
+
+False
+
+
+False
+
+
+
+False
+IONricIIR0WGo59WsXpFtgAA
+
+
+False
+IONricIIR0WGo59WsXpFtgAA
+
+
+
+
+38
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+xZ3+dsZIfEiC43OHIp6HbwAA
+OwFBa/th9Uy8Lm8eq4Aj4QAA
+c27YkTyoM0aKzvAZCm2iIgAA
+FQhWGDczYUyEyHgdkNc//gAA
+2
+
+0..*
+VBvmUm8cYUO9N+N5odPPwgAA
+1UxBGcFK3EKPBFhSfrqD/gAA
+4
+0fKpEItNIEyLVHn22yCbcgAA
+I/O9qvaRCkm2U9iU87kcegAA
+Kr274H6cB0uV7Jh3zEPCDwAA
+w8cW1VW7NEGh84PNhZoIKAAA
+
+
+akAggregate
+VBvmUm8cYUO9N+N5odPPwgAA
+Zb0aDQhc/0+9cFTqn86nzAAA
+4
+Tl6bZUBecES9Wf3QPI+W5gAA
+yZdaFpAs4U2WLaLyYzu4BAAA
+oveJexj1FUaO2/ZC0Yr20QAA
+ITJeMH8P+UGCKmh0E0oV+AAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+FJnWa3Qkd0Oa/L/Bnos5PwAA
+dtfpOxLsxEi76MixqvFxeAAA
+FNV9oBeYnEq1AKz4TK157QAA
+kskyU4LPAkeYLLAIBSQDqwAA
+2
+
+0..*
+Xyq6xieNl0Cn5MPsr7wH4gAA
+tPNexD/wZ0Kui7rS13cHiQAA
+4
+2E5HCfk9rUGK4qKkKTmuCAAA
+LMSNfK4lCEuMmi3UVWkLUQAA
+Xhy7Xm7Jy0eG8KMLyL+ItAAA
+DMDmkcKWpE64qvIf5u0vsAAA
+
+
+akAggregate
+Xyq6xieNl0Cn5MPsr7wH4gAA
+Zb0aDQhc/0+9cFTqn86nzAAA
+4
+PwBGm+gLokmVo1vE9urRjgAA
+nhGgwZkUGUijmCSxNabUfwAA
+D3w6jbaif0yLYBhIM21JzQAA
+h8N5Cnk8mU+N53/yc4WifgAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+33uAhI5hLUWb7Axy/eyXZgAA
+tUMOJDDxLUqqomPTayLrUQAA
+mm+t0pMG20KB7AwHTHzjWAAA
+/vtG/tvzPk2y2gPniiYPgQAA
+2
+
+0..*
+bgc8Y2rnekGMLllh30J1OQAA
+DEez7Bc9Uk2h44eLm4tOTAAA
+4
+q5R3azzdLEq9J9i5gPI0DAAA
+LS3AvKHSa02HeWvrF4I0owAA
+2yewimL/dk6m6bpFnRan+gAA
+hxIjQHEETUihPyBoroARPgAA
+
+
+akAggregate
+bgc8Y2rnekGMLllh30J1OQAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+3o8m9AMXSEyj9NuoG48g6AAA
+cqEDZ6uFDU+d99Mg4pdsRQAA
+4U3CJtdrSE6v0RtK8cfbmQAA
+DiasEUayJkiGpAbs8CCj1wAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+uIDgNBc5UU+LdBtKBxIR8gAA
+5tUhqIYIyU27VWbzjNQiKQAA
+5ppftDIPjUa6ZqVDeohPAAAA
+ihvFb0GsjkS5/O+Kun9vxwAA
+2
+
+0..1
+xX7RE0ASlkOrRf9dOxH/zgAA
+A9TZ2/XE7UqgiiSvVEDLQwAA
+4
+xpUbJo+EfEeDXJwxUI0rCAAA
+biEwgK/6UUeESLm1DAHiPwAA
+pJdulqbefkGnbq1iXskheQAA
+4e3r4Vq+7Uu1V8jh7OyJKgAA
+
+
+akAggregate
+xX7RE0ASlkOrRf9dOxH/zgAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+3lI3E9NaG0ecYhVlRZfMOgAA
+rMu4spxAdUKJKBpc2tyrNgAA
+Lkjawm3/i0GjCA4UEjTVWAAA
+08M182NXqUCM9djSdJom9wAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+2
+
+0..1
+IbSrQHThPkm7336xQuEr9QAA
+dQcGnfO8tUKc0D+z/TWjpgAA
+
+
+akAggregate
+IbSrQHThPkm7336xQuEr9QAA
+zjzhCfIGK0Ooz0gx49BvDwAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+2
+
+0..1
+YMOEI4D3GUKNGWbGDKOzZAAA
+A9TZ2/XE7UqgiiSvVEDLQwAA
+
+
+akAggregate
+YMOEI4D3GUKNGWbGDKOzZAAA
+dQcGnfO8tUKc0D+z/TWjpgAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+XcB/Q/sATESweCaW2t4wnQAA
+zKxSi5pvBEyo9pokzGV0nQAA
+a092OvmkWkKcH0d8lorXkwAA
+UBRCnMpUxUapUxmOYMTPhQAA
+2
+
+0..*
+jYjMEcDtz0aFEBPfn7j7/QAA
+5zzJFTvUNk2trdiXalmeUQAA
+4
+vwbK1pbOv02FS5I6Zmus5wAA
+2QeJVqdXo06b+P8rEGtegwAA
+k90lw606mEK4db48UMuY/wAA
++yXh9uY7k0iik/y2BVB3FwAA
+
+
+akAggregate
+jYjMEcDtz0aFEBPfn7j7/QAA
+qH8EpavZy0uYaWHuDNJMmwAA
+4
+suPFDNWV3UOb/+M8fH7y7wAA
+A66naIO5mkenjssIQuWtVAAA
+12LM0klzFkWFjNfvokdKGAAA
+r9b1icqUYUC8D2R1+xz7cgAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+WGg3rakepkWtBAqoWP44ywAA
+mQmYEEnXuUmEJj4piUmHowAA
+0G5mlrJr+Eiv4dfimQXojQAA
+YdgBHEDo8UG0pehkXHibOQAA
+2
+
+0..*
+FMFT2mNP8kuBwaPLNS+zWQAA
+RSfNCw5wNUGCDOhEi/bCrwAA
+4
+tIFm2Q+KGkizuJZ9/6nexQAA
+x2Fh6dvb0kCt53+FJQOT0wAA
+TChX1hF8602JC7MGrLA/IgAA
+XoROrupIIkugkyX8kIWoQQAA
+
+
+akAggregate
+FMFT2mNP8kuBwaPLNS+zWQAA
+5zzJFTvUNk2trdiXalmeUQAA
+4
+oRXm+3xyXUquxxvMBCrX6AAA
+JIbveD8ApUyCkEPBOuSwDAAA
+ydX7TsoJQUilkCbPAMy/jQAA
+z+rUEoZdm0KObqQEeWkbsgAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+2
+
+0..1
+NNofZFXapkSUSlwtLNERUAAA
+uLUfupUhTEy2wLImcq6rhwAA
+
+
+akAggregate
+NNofZFXapkSUSlwtLNERUAAA
+qH8EpavZy0uYaWHuDNJMmwAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+0hyPJ79WpEGOk+EFfFMj8AAA
+5LQZ7vYPHUGto5ewngofEwAA
+qbCamC1EF0uQywm8EGy8bgAA
+biqXKjM3Ek2ivOQJQZO+FAAA
+2
+
+0..*
+WyvGK0t/hESPxIXfgMmsXwAA
+ivlA8JWOIEOE/0Z2gIiUMAAA
+4
+eOlKymCtCkOGx1KgXpsgwwAA
+5tHt4ItsCkGUkVfd4UdrPAAA
+Q8U3oLdrLE2F5AtQ/C0DhwAA
+P/plYL/fbUCLyPvAe8Xb5gAA
+
+
+akAggregate
+WyvGK0t/hESPxIXfgMmsXwAA
+5zzJFTvUNk2trdiXalmeUQAA
+4
+ClejYgSmD0ecLH4SuH7/IQAA
+AAcCsmN/PUOAeQ94dDuc2wAA
+vUgzL99dqU62JX+eWE/+swAA
+G72vhO67tU+FvKsr+wbwvQAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+IFsLjjiZFUWiemuBScOPdwAA
+SfPmx9VC40y36maowqYE9gAA
+dCfwLT1Mi0uQiki30jg58wAA
++mZMtPs3FE+Yp7qmfXT6kgAA
+2
+
+0..*
+TBMgXpKOvkqNYUoAAwF/kwAA
+RR0EuzZlckCzW5H+HzADZAAA
+4
+VN6jbvdN0Eq5Z75i5FutKwAA
+p7x2bZh4P0+r2gl85iTL9QAA
+UOl1s6w3qkeExTCMQmUejQAA
+WhbvRyIYoEaZg82e7bNmQgAA
+
+
+akAggregate
+TBMgXpKOvkqNYUoAAwF/kwAA
+RSfNCw5wNUGCDOhEi/bCrwAA
+4
+Hrwon9AU20KBrLenzKCCJAAA
+NCx8+BohkkG8/3vayHPzUAAA
+Q15G0gVK50GhgDMyeL+n1AAA
+0TMEEeywLE24hl+z2wKOtgAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+cAti98LcSkS2mT0tBmFgXgAA
+DOUQLueVh06YyWL/PD21nwAA
+Cd7piLNWA0mAgjvLVavXTQAA
+0JpGkmClT0Gn2KUgtQJ5wwAA
+2
+
+0..*
+DrVKQ3pWaUi+uJD9jDo4mgAA
+RR0EuzZlckCzW5H+HzADZAAA
+4
+GrW/KPjagUOkA4kik0jnwwAA
+qxpRLqGUHUmujCT8CFiwTwAA
+iDS4D4p3wkGquvQu6b4BvQAA
+4VhMNvKIzESZo+RC2OQ22wAA
+
+
+akAggregate
+DrVKQ3pWaUi+uJD9jDo4mgAA
+ivlA8JWOIEOE/0Z2gIiUMAAA
+4
+U6af9iwY4Euj7+Pv6jQMxwAA
+FMoH3AVUskuTFAsg+/zS/gAA
+ymveNro9J0SmVCAIbKxYnAAA
+Tpaf2aSuWUmwb+CW46meEQAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+8EckyC2TmUuarEhp8FAySAAA
+2FPQ4Xkcy0azGg7GBNt9rwAA
+tsmfINAYAUq57iBKodP1fAAA
+XkyBeCmDf0S5CQ6ztHMNzgAA
+2
+
+0..*
++L/IOS7xU0CZQGaUuRo79wAA
+5zz6gIaMNUKuDMdUeCpo8AAA
+4
+pBqxLpNTIUu8G++vWA2aJQAA
+oDEdcF7BgEWVG/UO54xulQAA
+2jWAWOd/pUKdHuoh2Uwv5wAA
+VkFvWYP1FE+NB1AVf3BRZwAA
+
+
+akAggregate
++L/IOS7xU0CZQGaUuRo79wAA
+ivlA8JWOIEOE/0Z2gIiUMAAA
+4
+JLwEQ+OnK0K81MYE0IwDxAAA
+nn2UiGiRDE2R4H3exI7h6gAA
+ZwdNiLLuVkW5ypkoJbamnwAA
+0IN6dhUTmkO5BJJ0HuunmQAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+keuqwZ/b70O9JGtNWC1HOwAA
+TXT7PT01rUK8hWWcouQrqwAA
+p/xzX/wsJE2iH2iQKBfV6gAA
+bvte2UT4Hk2L6XiA6IW1oQAA
+2
+
+0..*
+o4nt6mUd0E+mlHL56Zp/egAA
+5zz6gIaMNUKuDMdUeCpo8AAA
+4
+lXiXD4C2AU6b5a6EbgVIpQAA
+lDGnXZzhbk67kSR0WhJW2QAA
+hsqzdQmMWEKu8ifaCZqRSAAA
+x2L2vrEHJU6bLG6YvmN+BgAA
+
+
+akAggregate
+o4nt6mUd0E+mlHL56Zp/egAA
+RSfNCw5wNUGCDOhEi/bCrwAA
+4
+OaKExY1aI02AMjQkxCLysQAA
+SB9KA5RQakKw8yg9PurfsgAA
+3FruEk6P60eJZ2yGPgdfqAAA
+imNjlVqaKke7tf3SjnP19AAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+Oyz3g+Eb+0aLBMMP2OdnywAA
+nALUx2T9Ek2OwwszSpQDZQAA
+1AfqmcpjFUqxPQk69aW+XgAA
+2gKd+sQZT0yFRQh0A9mb5AAA
+2
+
+0..*
+T6dZEmqJBk+JCBjNk+rKTgAA
+8qRD67PVK0aWXk0wa4g0EAAA
+4
+QufHXsbWl0WSow4YCLlr3QAA
+0jizQRMG7kGF2Ihk78xtLQAA
+8o0CenYCKkm2TwPtqznYVgAA
+26SPYXaf9kyQmuPCOLhxZAAA
+
+
+akAggregate
+T6dZEmqJBk+JCBjNk+rKTgAA
+bsLMfNcnMUOLwcGU0WrbswAA
+4
+p08f/TURiUuXtccGxGI10gAA
+U8VyjCE1+ESpHThR6j5jeQAA
+EcM/X/O720i4uubgSZgh8gAA
+XOW7tTTEHUy8X5gRLyzGzQAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+NbRVlVzojEy/Lq+DBHs5wAAA
+osmqNSG9XUmyM4IO4+pP+AAA
+TlF7nqwiKk6+wLo7NlpH9gAA
+Q+cxwoveCkeigaspgfX7JgAA
+2
+
+0..*
+bp+wZYcgB06p/FXxYnPeTwAA
+owewdd03PEqMInhVg8hxegAA
+4
+W9D4rtyWhUu4LVWN0R18+QAA
+tQkf5tlxJEC1xXIkDHKV8QAA
+iMaiGEU8WUq24TcEgWNe1gAA
+69sDpwOjyUm2y2rmEdZ31gAA
+
+
+akAggregate
+bp+wZYcgB06p/FXxYnPeTwAA
+8qRD67PVK0aWXk0wa4g0EAAA
+4
+M8HJcPL9qk+XCdB9mxXCGwAA
+Srn6vi9WtE+f+sBRNq53WgAA
+vIvkfgU6eEqHe14QMZtKwAAA
+a2Mk9EYtl0CIEogV7Q8rYwAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+dLWcwxVERkGRdXFNtBJxSgAA
+fi7JFxBqykSKlYSmEXn0YgAA
+7rvLfWINwECFyjNqf5+1ugAA
+javyJkUdeUGEYWXn5RsElAAA
+2
+
+0..2
+kRhs7Db07UCnVGvTeUn8qgAA
+RH51ga45KE6KDoeLQE8QlQAA
+4
+zuVp2v+ehEOqKJcMTlKiQAAA
+Ubfg9u6qUE2EwVbLux9JcgAA
+cPdSWjZ5NEuBpfrIAx3rYAAA
+9grqcoX0n0WN2qPf2TC/iwAA
+
+
+akAggregate
+kRhs7Db07UCnVGvTeUn8qgAA
+bsLMfNcnMUOLwcGU0WrbswAA
+4
+mLfeBa3PtkOo6uvLbzwmWQAA
+7w3JfnHZSEiz51HcCeTD0gAA
+wEaj9RGukkK91gRZ9BNeowAA
+D8eh27iipUigD3DOeweTgwAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+YnexAQXCSEmdRB4mzG2eDAAA
+6R2FOEPEREub7zclEMKu7QAA
+hvvGcnL/aUG2lUskmWcyVgAA
+GahVFnML8U+n3sq4jSuybwAA
+2
+
+0..*
+eb3ayVr/ukqo6hvbKDz/swAA
+LyqVpBJycU+8Cyr2qe1BvAAA
+4
+tEA8cl7lHEO8LOt56RhoCQAA
+xj10XT1n1UCWgHaZncTTGgAA
+5c/P9C3GDU6RvQUbTcNiLgAA
+BFna1MLap0Cde8OsO8HmlgAA
+
+
+akAggregate
+eb3ayVr/ukqo6hvbKDz/swAA
+bsLMfNcnMUOLwcGU0WrbswAA
+4
+UuiygYFsvEqjuBpVAK+QYgAA
+JZfOJJlwCkSzGpsVbu5l5QAA
+3nvXpaiPaEWwGDRUCky1DAAA
+vgPoo8+OM02s/JymWoSSHQAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
++ajNiZhtfkqr4Ip+H9i7ygAA
+xEmIj3vizUyc8IeHzZzehgAA
+jm13hIyI3k2LrpIL5e0jNQAA
+DMeHYWv+s0agt3t1wzwM1QAA
+2
+
+0..2
+uqzj6Tgi3UqwZ2fIPCUxxgAA
+RH51ga45KE6KDoeLQE8QlQAA
+4
+fKYHJ5cc1k+APkFy8CvvxwAA
+FTmXdCOLlk2ky3vVlEbyJgAA
+0pZdlegq40ak5db1s7bKkAAA
+ZMLXleFVeEmCF/KGwnv8yAAA
+
+
+akAggregate
+uqzj6Tgi3UqwZ2fIPCUxxgAA
+LyqVpBJycU+8Cyr2qe1BvAAA
+4
+9ay94DWRiUaWXzZBc+zNCAAA
+hBhmpDWP6kyFVSNGduiusAAA
+pyk4GBNMuESdYmyhGJB5GAAA
+9bNtG1JQOEWudwR9deV29AAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+hwJMwHLkvUG+IsAaCaziqwAA
+KYhSQdxF2ESNumBL6XCXSAAA
+Avl0Bwz1g0mTxAt22ofQygAA
+Cbymk6DX80ezDS9Hc235CwAA
+2
+
+0..2
+kXQY/Vx23UC1DCh8F9IRdQAA
+RH51ga45KE6KDoeLQE8QlQAA
+4
+T/ua+KCigE20Gfl/dJ4XrQAA
+KrSmFvVFOUK62Gbf5HAMPQAA
+qQYS/rwfTke5k4gCNB2yXQAA
+/ENNOk7hbESKFw4vl2LbqQAA
+
+
+akAggregate
+kXQY/Vx23UC1DCh8F9IRdQAA
+8qRD67PVK0aWXk0wa4g0EAAA
+4
+/X35LDb+DEiJXnNfVU2rdAAA
+vSkSRdqBp0WIvH69UZgUNgAA
+U8Asfcm4x0m9eo1mJ54HqwAA
+90A2D258u0CKJ56gBl6brgAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
++KAZSHjliE20MOigCSjtswAA
+sBuc1XPgEEqF7cNlI6g8fAAA
+ZdaGtQlOBEyWh+XqTEYoaQAA
+3ogUEW08UU6YGhRDKod94gAA
+2
+
+0..*
+i+idGeRyH0O6Trx2aQWMcwAA
+8qRD67PVK0aWXk0wa4g0EAAA
+4
+cIX+mr93JEG2b8kI8CaJ4QAA
+l6EeEQrG0UG3x4QS2FtNnAAA
+gc5YwU7ap0uUsjn1ia0pMAAA
+HhbrxzkVrUq6n0+QjfKfSAAA
+
+
+akAggregate
+i+idGeRyH0O6Trx2aQWMcwAA
+LyqVpBJycU+8Cyr2qe1BvAAA
+4
+1H6EHKqhr06EQGdQOXQK7gAA
+I9NVsfIvLU+QtoEeKdFiaQAA
+61URF7/rmkGbZG9o4j3/8AAA
+H3+QpAFFCEqLMC2AZU5STwAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+iN8vizAkO0SdgDkxW75xWQAA
+9isiJhLnKEqUzJ0bbm2prgAA
+yxDY2j0ycUKvrfzBqyMY+AAA
+y2AXYAqQe0iKD6O8s23/HQAA
+2
+
+0..*
+POwBB4/GAUeNaKKEcJpIlQAA
+eYGzjuCMLkKn4NjB0dEn0AAA
+4
+gLKU7VT0fkaL49FlQlsFwAAA
+N7cRTUq3k0qbJpPo2FrXUQAA
+vcTkKyxY4Uy0P3Dn4XpEbAAA
+4WLr8c1VmEapx+ZiSHSFVwAA
+
+
+akAggregate
+POwBB4/GAUeNaKKEcJpIlQAA
+8qRD67PVK0aWXk0wa4g0EAAA
+4
+sypIgjQeU02cHtbTtCyfDwAA
+3lDt7gvTSECW3UteHCcrSQAA
+fTGcxOEsP0GMN9kamSHNUgAA
+HiOYXtGhm0GbNpW1wzW3EQAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+QPqO0H5L8k2iFBlLAttNygAA
+sTOShnMgm0OduL1pZBjh4gAA
+TSykHjiLO0a7eeu56HCWPwAA
+6pis0rkULE2W7zVj1mHZ3wAA
+2
+
+0..*
+XTynUTFt8Uum/xg/s19W6wAA
+ThAFaRsy80+bQYf7JAabBwAA
+4
+vHO4Vhf2ZEqlogODaJ10zQAA
+lnMqxzb1n0W3K8eG1ArDGAAA
+8vT/yzrUvEyljses/cgtrwAA
+8OzzVjYwGUC0SFgk3vBufQAA
+
+
+akAggregate
+XTynUTFt8Uum/xg/s19W6wAA
+xCbPvrEvREGZaSAQo1zNTQAA
+4
+0OMZR1LsXUa8x9hhs4WErQAA
+YQyzCDdjXE2DxROvAIO/yQAA
++Fo45RZAe0+nNxFRsmflUwAA
+Jq2BMndNmkGdi2gpj8/qxAAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+kZ03rRdVdUqEFU4k1XVjqwAA
+d8e/my45lEWzg+JM7UUGfgAA
+kVXJnrU6U0mpt7I8dWwEbAAA
+NRxuhOrTdU+rCPNNNcvayQAA
+2
+
+0..*
+utDCx5aE6ky22jhkB2Oi7AAA
+murMcFQfV0C/t/mMWAPhwAAA
+4
+xg3N1O01k06cQuUeoPYyFAAA
+Rirsu7gAwkOVobuUxPBoBQAA
+SFlaKylCX0K2dXnYaZ9F6QAA
+HS7Exc2EZUWzFQft84i/CgAA
+
+
+akAggregate
+utDCx5aE6ky22jhkB2Oi7AAA
+ThAFaRsy80+bQYf7JAabBwAA
+4
+CCY8TbsGgEipJdFhEKtzKwAA
+B3jktLZVrECOZAyEBBw+VwAA
+4UNUI+77VUyvjrzdLLP2awAA
+SebPLgGPaUO+AlHoO+xDeAAA
+
+
+
+8/PDgZYaSkyhn9djg2OS7wAA
+4
+DQB2/Uad90yVchVQBxQShwAA
+DREKim22IEGrf/G0tKQIqQAA
+N53C04fLC0aGrU+rDwWcMQAA
+HF1V+Dt9CkCwImf2IEeIYAAA
+2
+
+0..*
+u0qI6rv6oUOx4Rjd0HaoZQAA
+YNCQ6GQz3Ee39yEg7TDrrAAA
+4
+5EbFltXbuUCDoif+I3WsMgAA
+aCxw81qbYECFkyLUWcf7PgAA
+s4dnTipnd0SaJY8KGHopsAAA
+kHRrm2Bs50OvsCxBiYlR6wAA
+
+
+akAggregate
+u0qI6rv6oUOx4Rjd0HaoZQAA
+ThAFaRsy80+bQYf7JAabBwAA
+4
++kptnbelkU+0NbAjgOPs7wAA
+9n3HLEgujEiyw9t/aAXfRgAA
+U5Q0zwneZEacDWw0mTwFMQAA
+qVv7yx70k0qkmlT3pxZ1OgAA
+
+
+
+commandml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+commandml
+YKLbxJmpOECbtM/emMmnLwAA
+
+kErI+FlvY0+kAST0Q9l4fQAA
+12
+
+clMaroon
+$00B9FFFF
+180
+60
+116
+43
+xCbPvrEvREGZaSAQo1zNTQAA
+
+
+1
+<<commandml>>
+
+
+False
+
+
+False
+
+
+
+False
+xCbPvrEvREGZaSAQo1zNTQAA
+
+
+False
+xCbPvrEvREGZaSAQo1zNTQAA
+
+
+False
+xCbPvrEvREGZaSAQo1zNTQAA
+
+
+
+clMaroon
+$00B9FFFF
+196
+156
+80
+98
+False
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+1
+command
+
+
+False
+
+
+False
+
+
+
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+False
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+False
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+237,156;237,102
+XTynUTFt8Uum/xg/s19W6wAA
+1GuMUA7uD0iOm5T5ALuDEgAA
+tlXrSjr3LESaFOwUzCjBrgAA
+
+False
+1.5707963267949
+15
+XTynUTFt8Uum/xg/s19W6wAA
+
+
+False
+1.5707963267949
+30
+XTynUTFt8Uum/xg/s19W6wAA
+
+
+False
+-1.5707963267949
+15
+XTynUTFt8Uum/xg/s19W6wAA
+
+
+False
+-0.523598775598299
+30
+epHead
+qa409uRzmEiwyt0p27OyagAA
+
+
+False
+0.523598775598299
+30
+epTail
+Bbt4Y4RR0E2BTPphWVhB8wAA
+
+
+False
+0.523598775598299
+25
+epHead
+qa409uRzmEiwyt0p27OyagAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+Bbt4Y4RR0E2BTPphWVhB8wAA
+
+
+False
+-0.785398163397448
+40
+epHead
+qa409uRzmEiwyt0p27OyagAA
+
+
+False
+0.785398163397448
+40
+epTail
+Bbt4Y4RR0E2BTPphWVhB8wAA
+
+
+False
+-1000
+-1000
+50
+8
+qa409uRzmEiwyt0p27OyagAA
+
+
+False
+-1000
+-1000
+50
+8
+Bbt4Y4RR0E2BTPphWVhB8wAA
+
+
+
+clMaroon
+$00B9FFFF
+252
+324
+86
+46
+False
+murMcFQfV0C/t/mMWAPhwAAA
+
+
+1
+argument
+
+
+False
+
+
+False
+
+
+
+murMcFQfV0C/t/mMWAPhwAAA
+
+
+False
+murMcFQfV0C/t/mMWAPhwAAA
+
+
+False
+murMcFQfV0C/t/mMWAPhwAAA
+
+
+
+clMaroon
+$00B9FFFF
+285,324;255,253
+utDCx5aE6ky22jhkB2Oi7AAA
+tlXrSjr3LESaFOwUzCjBrgAA
+uNpredncAUiIIb0omn0rSwAA
+
+False
+1.5707963267949
+15
+utDCx5aE6ky22jhkB2Oi7AAA
+
+
+False
+1.5707963267949
+30
+utDCx5aE6ky22jhkB2Oi7AAA
+
+
+False
+-1.5707963267949
+15
+utDCx5aE6ky22jhkB2Oi7AAA
+
+
+False
+-0.523598775598299
+30
+epHead
+SMaE6mVo9UaeI5aptbrc+gAA
+
+
+False
+0.523598775598299
+30
+epTail
+p/U6E0BcgEOzHgIvJgE+vAAA
+
+
+False
+0.523598775598299
+25
+epHead
+SMaE6mVo9UaeI5aptbrc+gAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+p/U6E0BcgEOzHgIvJgE+vAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+SMaE6mVo9UaeI5aptbrc+gAA
+
+
+False
+0.785398163397448
+40
+epTail
+p/U6E0BcgEOzHgIvJgE+vAAA
+
+
+False
+-1000
+-1000
+50
+8
+SMaE6mVo9UaeI5aptbrc+gAA
+
+
+False
+-1000
+-1000
+50
+8
+p/U6E0BcgEOzHgIvJgE+vAAA
+
+
+
+clMaroon
+$00B9FFFF
+124
+320
+91
+59
+False
+YNCQ6GQz3Ee39yEg7TDrrAAA
+
+
+1
+pipe
+
+
+False
+
+
+False
+
+
+
+YNCQ6GQz3Ee39yEg7TDrrAAA
+
+
+False
+YNCQ6GQz3Ee39yEg7TDrrAAA
+
+
+False
+YNCQ6GQz3Ee39yEg7TDrrAAA
+
+
+
+clMaroon
+$00B9FFFF
+182,320;213,253
+u0qI6rv6oUOx4Rjd0HaoZQAA
+tlXrSjr3LESaFOwUzCjBrgAA
+hBnfhqGe60WZZN0uD1pavwAA
+
+False
+1.5707963267949
+15
+u0qI6rv6oUOx4Rjd0HaoZQAA
+
+
+False
+1.5707963267949
+30
+u0qI6rv6oUOx4Rjd0HaoZQAA
+
+
+False
+-1.5707963267949
+15
+u0qI6rv6oUOx4Rjd0HaoZQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+Wbh515voZUSZ+lPync1/wwAA
+
+
+False
+0.523598775598299
+30
+epTail
+RPEMUfaL1Umf648f3atFIAAA
+
+
+False
+0.523598775598299
+25
+epHead
+Wbh515voZUSZ+lPync1/wwAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+RPEMUfaL1Umf648f3atFIAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+Wbh515voZUSZ+lPync1/wwAA
+
+
+False
+0.785398163397448
+40
+epTail
+RPEMUfaL1Umf648f3atFIAAA
+
+
+False
+-1000
+-1000
+50
+8
+Wbh515voZUSZ+lPync1/wwAA
+
+
+False
+-1000
+-1000
+50
+8
+RPEMUfaL1Umf648f3atFIAAA
+
+
+
+clMaroon
+$00B9FFFF
+372
+180
+90
+46
+False
+4iLeTKCC5U6MSHKinrEQxwAA
+
+
+1
+condition
+
+
+False
+
+
+False
+
+
+
+4iLeTKCC5U6MSHKinrEQxwAA
+
+
+False
+4iLeTKCC5U6MSHKinrEQxwAA
+
+
+False
+4iLeTKCC5U6MSHKinrEQxwAA
+
+
+
+clMaroon
+$00B9FFFF
+383,180;268,102
+TfyrXyJmbU61xKYCsJzibAAA
+1GuMUA7uD0iOm5T5ALuDEgAA
+IP1NUwGChEG75rlr5pHxkgAA
+
+False
+1.5707963267949
+15
+TfyrXyJmbU61xKYCsJzibAAA
+
+
+False
+1.5707963267949
+30
+TfyrXyJmbU61xKYCsJzibAAA
+
+
+False
+-1.5707963267949
+15
+TfyrXyJmbU61xKYCsJzibAAA
+
+
+False
+-0.523598775598299
+30
+epHead
+Zov7rrxjQEqiPfV+IkZbBgAA
+
+
+False
+0.523598775598299
+30
+epTail
+m6Z//ASd5UC3bvGU2ZQhpwAA
+
+
+False
+0.523598775598299
+25
+epHead
+Zov7rrxjQEqiPfV+IkZbBgAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+m6Z//ASd5UC3bvGU2ZQhpwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+Zov7rrxjQEqiPfV+IkZbBgAA
+
+
+False
+0.785398163397448
+40
+epTail
+m6Z//ASd5UC3bvGU2ZQhpwAA
+
+
+False
+-1000
+-1000
+50
+8
+Zov7rrxjQEqiPfV+IkZbBgAA
+
+
+False
+-1000
+-1000
+50
+8
+m6Z//ASd5UC3bvGU2ZQhpwAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+275,204;372,204
+Fo00uYOQDEKWjo+4JES7rAAA
+IP1NUwGChEG75rlr5pHxkgAA
+tlXrSjr3LESaFOwUzCjBrgAA
+
+False
+1.5707963267949
+15
+Fo00uYOQDEKWjo+4JES7rAAA
+
+
+False
+1.5707963267949
+30
+Fo00uYOQDEKWjo+4JES7rAAA
+
+
+False
+-1.5707963267949
+15
+Fo00uYOQDEKWjo+4JES7rAAA
+
+
+False
+-0.523598775598299
+30
+epHead
+r1eec5hmmUOQVpiNC3y6jAAA
+
+
+False
+0.523598775598299
+30
+epTail
+zthvNu6Bb0G05kGsMvowkwAA
+
+
+False
+0.523598775598299
+25
+epHead
+r1eec5hmmUOQVpiNC3y6jAAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+zthvNu6Bb0G05kGsMvowkwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+r1eec5hmmUOQVpiNC3y6jAAA
+
+
+False
+0.785398163397448
+40
+epTail
+zthvNu6Bb0G05kGsMvowkwAA
+
+
+False
+-1000
+-1000
+50
+8
+r1eec5hmmUOQVpiNC3y6jAAA
+
+
+False
+-1000
+-1000
+50
+8
+zthvNu6Bb0G05kGsMvowkwAA
+
+
+
+clMaroon
+$00B9FFFF
+384
+280
+86
+95
+False
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+1
+filter
+
+
+False
+
+
+False
+
+
+
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+False
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+False
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+
+clMaroon
+$00B9FFFF
+384,300;275,230
+qFDuzmHTkk24gp7JWgucBwAA
+tlXrSjr3LESaFOwUzCjBrgAA
+PwZTXFb9vEyu4nNghuE8cgAA
+
+False
+1.5707963267949
+15
+qFDuzmHTkk24gp7JWgucBwAA
+
+
+False
+1.5707963267949
+30
+qFDuzmHTkk24gp7JWgucBwAA
+
+
+False
+-1.5707963267949
+15
+qFDuzmHTkk24gp7JWgucBwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+yi3TdlMWv0yNevDHzJ5umQAA
+
+
+False
+0.523598775598299
+30
+epTail
+it8oL7K2G0OWf9i5jlTy/AAA
+
+
+False
+0.523598775598299
+25
+epHead
+yi3TdlMWv0yNevDHzJ5umQAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+it8oL7K2G0OWf9i5jlTy/AAA
+
+
+False
+-0.785398163397448
+40
+epHead
+yi3TdlMWv0yNevDHzJ5umQAA
+
+
+False
+0.785398163397448
+40
+epTail
+it8oL7K2G0OWf9i5jlTy/AAA
+
+
+False
+-1000
+-1000
+50
+8
+yi3TdlMWv0yNevDHzJ5umQAA
+
+
+False
+-1000
+-1000
+50
+8
+it8oL7K2G0OWf9i5jlTy/AAA
+
+
+
+
+9
+
+<<commandml>>
+YKLbxJmpOECbtM/emMmnLwAA
+4
+1GuMUA7uD0iOm5T5ALuDEgAA
+IZe1/VFei0yx34tqNHrtAgAA
+v4pvulgn+02Tu0tznRmisQAA
+RPCpiqsOEE28et4OHJfCfwAA
+2
+qa409uRzmEiwyt0p27OyagAA
+Zov7rrxjQEqiPfV+IkZbBgAA
+
+
+command
+YKLbxJmpOECbtM/emMmnLwAA
+4
+tlXrSjr3LESaFOwUzCjBrgAA
+WkqEcfJ0pUm7mEMU2P3boQAA
+8YweCFP2lke8H6Qfw5MCggAA
+y6gW5chxUU6VDNiVkEwsigAA
+5
+Bbt4Y4RR0E2BTPphWVhB8wAA
+SMaE6mVo9UaeI5aptbrc+gAA
+Wbh515voZUSZ+lPync1/wwAA
+zthvNu6Bb0G05kGsMvowkwAA
+yi3TdlMWv0yNevDHzJ5umQAA
+5
+
+executable
+1
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+shell
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+bufsize
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+cwd
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+env
+ThAFaRsy80+bQYf7JAabBwAA
+
+
+
+pipe
+YKLbxJmpOECbtM/emMmnLwAA
+4
+hBnfhqGe60WZZN0uD1pavwAA
+6kjsjt214kCJQgwfrTIdQgAA
++4adbxUm/UGfWDLn2PlaRAAA
+JWUUEw/yVE+tLN18ZioF7AAA
+1
+RPEMUfaL1Umf648f3atFIAAA
+2
+
+name
+1
+YNCQ6GQz3Ee39yEg7TDrrAAA
+
+
+value
+1
+YNCQ6GQz3Ee39yEg7TDrrAAA
+
+
+
+argument
+YKLbxJmpOECbtM/emMmnLwAA
+4
+uNpredncAUiIIb0omn0rSwAA
+wy5SdbnypUSWFa49XbyErAAA
+c1q8cRvfMEGGd4nOpjRdhQAA
+nWnK2waRSk2H4fxDwHXxDAAA
+1
+p/U6E0BcgEOzHgIvJgE+vAAA
+1
+
+value
+1
+murMcFQfV0C/t/mMWAPhwAAA
+
+
+
+condition
+YKLbxJmpOECbtM/emMmnLwAA
+4
+IP1NUwGChEG75rlr5pHxkgAA
+t+jFABKzvEavur/RthEwDQAA
+tlCrqRJl1Eu7/0HHvi6WngAA
+9At+9vEGu0mzAlcYiMffQgAA
+2
+m6Z//ASd5UC3bvGU2ZQhpwAA
+r1eec5hmmUOQVpiNC3y6jAAA
+1
+
+value
+4iLeTKCC5U6MSHKinrEQxwAA
+
+
+
+YKLbxJmpOECbtM/emMmnLwAA
+4
+uyyviBKGHkqSRS6aa7BK4wAA
+UbT3thSm+k67bRr7M2hgTwAA
+8vMrS6pgn0+uer1v+x3zzAAA
+ycjaVEk3CUyjMQWq32597AAA
+2
+
+0..*
+TfyrXyJmbU61xKYCsJzibAAA
+4iLeTKCC5U6MSHKinrEQxwAA
+4
+294OFrDWR0ixb9mrh5dNHQAA
+Vc9zKqt0J0KqduwuCwrImAAA
+4u+ipLslHUqvbj8DnwqrewAA
+eCKa6YUesU+k6SZcTpOrAgAA
+
+
+akAggregate
+TfyrXyJmbU61xKYCsJzibAAA
+xCbPvrEvREGZaSAQo1zNTQAA
+4
+P+bdXLOT10KFtrcSuRRgigAA
+oZ4And/flEua017k7tYAVAAA
+fUhONjwplkOPTcEcyC9xTAAA
+XZZIZcptDUG1Ysc3gTOgpgAA
+
+
+
+YKLbxJmpOECbtM/emMmnLwAA
+4
+fUh8ZlulHkOKNSSfoC/u9QAA
+4LTqgr6VQEunDbH5TlBIpQAA
+V8CWN25/GUiTYlxNYxb86gAA
+ZBirdZVEkE2lnHy6XxtxMgAA
+2
+
+0..*
+Fo00uYOQDEKWjo+4JES7rAAA
+ThAFaRsy80+bQYf7JAabBwAA
+4
+9AEZMrD4ZEi+Jnx5OTbJ0gAA
+/kWBwEow5k6vEjTEeU9jdAAA
+8V15J2uX306aCe/vidRgggAA
+D5uB6bDIdk+DH117313X5QAA
+
+
+akAggregate
+Fo00uYOQDEKWjo+4JES7rAAA
+4iLeTKCC5U6MSHKinrEQxwAA
+4
+KtEaT15WUk6kc85q0D6coAAA
+IaP40maAVkiimv02l3ek2gAA
+6rO3/106lUO5thZTl5QszQAA
+0rFgnP20zUmUyDNPt71WjQAA
+
+
+
+filter
+YKLbxJmpOECbtM/emMmnLwAA
+4
+PwZTXFb9vEyu4nNghuE8cgAA
+cu+t+stSIUSVBOW4WqvaeAAA
+ykUMFIlTgUy1VZ6WxQgWewAA
+bCVaFurGhU6+GxKC+tOY2QAA
+1
+it8oL7K2G0OWf9i5jlTy/AAA
+4
+
+severity
+1
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+condition
+1
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+input
+1
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+formatter
+0..1
+4yP+KZkgKUeDDlNYajqefgAA
+
+
+
+YKLbxJmpOECbtM/emMmnLwAA
+4
+o3P7d2oa3Emys+undX+SZQAA
+5VTWbxJdP0qBqvVMzfxh4AAA
+/LwAzUP230C36V6pywg4LgAA
+z6TH02YmpE+CgGH0cTRoEAAA
+2
+
+0..*
+qFDuzmHTkk24gp7JWgucBwAA
+4yP+KZkgKUeDDlNYajqefgAA
+4
+3DCe2Gy2bkuUHfw1Fh4rfAAA
+uD707gJKXUq8+WABGZtABQAA
+gdNR3N6OEUK0UjZdbvGfxwAA
+MXQShAklZEWswk8BFwdzmgAA
+
+
+akAggregate
+qFDuzmHTkk24gp7JWgucBwAA
+ThAFaRsy80+bQYf7JAabBwAA
+4
+ClkdjiDFs0uvnN3NpsfSkAAA
+0AhjLJdiQkqVhvsOWkamowAA
+n6xMoVQfYE2urz66Qn6oYgAA
+BPOh5jgDIE6xIRVZkBLXkAAA
+
+
+
+
+content2
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+content2
+3q8/Gqy8BE6llPh/zkCQ1QAA
+
+0XBGlaeYa0mhVvT7HmGlpgAA
+13
+
+clMaroon
+$00B9FFFF
+120
+60
+110
+37
+False
+qH8EpavZy0uYaWHuDNJMmwAA
+
+
+1
+<<content v.2>>
+
+
+False
+
+
+False
+
+
+
+False
+qH8EpavZy0uYaWHuDNJMmwAA
+
+
+False
+qH8EpavZy0uYaWHuDNJMmwAA
+
+
+False
+qH8EpavZy0uYaWHuDNJMmwAA
+
+
+
+clMaroon
+$00B9FFFF
+132
+176
+80
+72
+False
+5zzJFTvUNk2trdiXalmeUQAA
+
+
+1
+output
+
+
+False
+
+
+False
+
+
+
+5zzJFTvUNk2trdiXalmeUQAA
+
+
+False
+5zzJFTvUNk2trdiXalmeUQAA
+
+
+False
+5zzJFTvUNk2trdiXalmeUQAA
+
+
+
+clMaroon
+$00B9FFFF
+172,176;174,96
+jYjMEcDtz0aFEBPfn7j7/QAA
+f8VxW8OVdEC1Ifglf0w3KQAA
+VqsyvTGqykGXuB4//e+E1QAA
+
+False
+1.5707963267949
+15
+jYjMEcDtz0aFEBPfn7j7/QAA
+
+
+False
+1.5707963267949
+30
+jYjMEcDtz0aFEBPfn7j7/QAA
+
+
+False
+-1.5707963267949
+15
+jYjMEcDtz0aFEBPfn7j7/QAA
+
+
+False
+-0.523598775598299
+30
+epHead
+rXN+Z0guxUy+Rz7TPELWrwAA
+
+
+False
+0.523598775598299
+30
+epTail
+Oz+BmuTcoUOLIBa7KS6DCQAA
+
+
+False
+0.523598775598299
+25
+epHead
+rXN+Z0guxUy+Rz7TPELWrwAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+Oz+BmuTcoUOLIBa7KS6DCQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+rXN+Z0guxUy+Rz7TPELWrwAA
+
+
+False
+0.785398163397448
+40
+epTail
+Oz+BmuTcoUOLIBa7KS6DCQAA
+
+
+False
+-1076
+-1000
+50
+8
+rXN+Z0guxUy+Rz7TPELWrwAA
+
+
+False
+-1076
+-1000
+50
+8
+Oz+BmuTcoUOLIBa7KS6DCQAA
+
+
+
+clMaroon
+$00B9FFFF
+200
+308
+101
+59
+False
+RSfNCw5wNUGCDOhEi/bCrwAA
+
+
+1
+input
+
+
+False
+
+
+False
+
+
+
+RSfNCw5wNUGCDOhEi/bCrwAA
+
+
+False
+RSfNCw5wNUGCDOhEi/bCrwAA
+
+
+False
+RSfNCw5wNUGCDOhEi/bCrwAA
+
+
+
+clMaroon
+$00B9FFFF
+232,308;194,247
+FMFT2mNP8kuBwaPLNS+zWQAA
+VqsyvTGqykGXuB4//e+E1QAA
+xIrnHgVLxUm97jUu4dACtAAA
+
+False
+1.5707963267949
+15
+FMFT2mNP8kuBwaPLNS+zWQAA
+
+
+False
+1.5707963267949
+30
+FMFT2mNP8kuBwaPLNS+zWQAA
+
+
+False
+-1.5707963267949
+15
+FMFT2mNP8kuBwaPLNS+zWQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+lKnU1zst3E2NB7kzxoZgugAA
+
+
+False
+0.523598775598299
+30
+epTail
+nckaYJRIc0C6lCvSiTPB3gAA
+
+
+False
+0.523598775598299
+25
+epHead
+lKnU1zst3E2NB7kzxoZgugAA
+
+
+4.9932447272606
+13.4536240470737
+epTail
+0..*
+nckaYJRIc0C6lCvSiTPB3gAA
+
+
+False
+-0.785398163397448
+40
+epHead
+lKnU1zst3E2NB7kzxoZgugAA
+
+
+False
+0.785398163397448
+40
+epTail
+nckaYJRIc0C6lCvSiTPB3gAA
+
+
+False
+-1076
+-1000
+50
+8
+lKnU1zst3E2NB7kzxoZgugAA
+
+
+False
+-1076
+-1000
+50
+8
+nckaYJRIc0C6lCvSiTPB3gAA
+
+
+
+clMaroon
+$00B9FFFF
+96
+308
+87
+59
+False
+ivlA8JWOIEOE/0Z2gIiUMAAA
+
+
+1
+externalinput
+
+
+False
+
+
+False
+
+
+
+ivlA8JWOIEOE/0Z2gIiUMAAA
+
+
+False
+ivlA8JWOIEOE/0Z2gIiUMAAA
+
+
+False
+ivlA8JWOIEOE/0Z2gIiUMAAA
+
+
+
+clMaroon
+$00B9FFFF
+146,308;162,247
+WyvGK0t/hESPxIXfgMmsXwAA
+VqsyvTGqykGXuB4//e+E1QAA
+hiEBWGBHwkiFkbHZnmNXjwAA
+
+False
+1.5707963267949
+15
+WyvGK0t/hESPxIXfgMmsXwAA
+
+
+False
+1.5707963267949
+30
+WyvGK0t/hESPxIXfgMmsXwAA
+
+
+False
+-1.5707963267949
+15
+WyvGK0t/hESPxIXfgMmsXwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+UXpHqpXWWkWaXmnhdMf/GwAA
+
+
+False
+0.523598775598299
+30
+epTail
+3UfPK4/xyES+AyWGHmWJsQAA
+
+
+False
+0.523598775598299
+25
+epHead
+UXpHqpXWWkWaXmnhdMf/GwAA
+
+
+-5.11361760228685
+15.6524758424985
+epTail
+0..*
+3UfPK4/xyES+AyWGHmWJsQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+UXpHqpXWWkWaXmnhdMf/GwAA
+
+
+False
+0.785398163397448
+40
+epTail
+3UfPK4/xyES+AyWGHmWJsQAA
+
+
+False
+-1000
+-1000
+50
+8
+UXpHqpXWWkWaXmnhdMf/GwAA
+
+
+False
+-1000
+-1000
+50
+8
+3UfPK4/xyES+AyWGHmWJsQAA
+
+
+
+clMaroon
+$00B9FFFF
+212
+428
+80
+59
+False
+RR0EuzZlckCzW5H+HzADZAAA
+
+
+1
+include
+
+
+False
+
+
+False
+
+
+
+RR0EuzZlckCzW5H+HzADZAAA
+
+
+False
+RR0EuzZlckCzW5H+HzADZAAA
+
+
+False
+RR0EuzZlckCzW5H+HzADZAAA
+
+
+
+clMaroon
+$00B9FFFF
+251,428;250,366
+TBMgXpKOvkqNYUoAAwF/kwAA
+xIrnHgVLxUm97jUu4dACtAAA
+Ge7hwnTE00+T03ai+/7E4QAA
+
+False
+1.5707963267949
+15
+TBMgXpKOvkqNYUoAAwF/kwAA
+
+
+False
+1.5707963267949
+30
+TBMgXpKOvkqNYUoAAwF/kwAA
+
+
+False
+-1.5707963267949
+15
+TBMgXpKOvkqNYUoAAwF/kwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+KX2YnwUuo0G17Q+mXzzS2wAA
+
+
+False
+0.523598775598299
+30
+epTail
+Lezmq5MfFEew6znmWvrvMAAA
+
+
+False
+0.523598775598299
+25
+epHead
+KX2YnwUuo0G17Q+mXzzS2wAA
+
+
+5.22798466438914
+19.723082923316
+epTail
+0..*
+Lezmq5MfFEew6znmWvrvMAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+KX2YnwUuo0G17Q+mXzzS2wAA
+
+
+False
+0.785398163397448
+40
+epTail
+Lezmq5MfFEew6znmWvrvMAAA
+
+
+False
+-1000
+-944
+50
+8
+KX2YnwUuo0G17Q+mXzzS2wAA
+
+
+False
+-1000
+-944
+50
+8
+Lezmq5MfFEew6znmWvrvMAAA
+
+
+
+clMaroon
+$00B9FFFF
+224,428;166,366
+DrVKQ3pWaUi+uJD9jDo4mgAA
+hiEBWGBHwkiFkbHZnmNXjwAA
+Ge7hwnTE00+T03ai+/7E4QAA
+
+False
+1.5707963267949
+15
+DrVKQ3pWaUi+uJD9jDo4mgAA
+
+
+False
+1.5707963267949
+30
+DrVKQ3pWaUi+uJD9jDo4mgAA
+
+
+False
+-1.5707963267949
+15
+DrVKQ3pWaUi+uJD9jDo4mgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+8TqXpAmOBEiEDJ5OcyQ/XQAA
+
+
+False
+0.523598775598299
+30
+epTail
+HJqngn7i40G7I2drQ2M13AAA
+
+
+False
+0.523598775598299
+25
+epHead
+8TqXpAmOBEiEDJ5OcyQ/XQAA
+
+
+5.01196091937824
+16.1245154965971
+epTail
+0..*
+HJqngn7i40G7I2drQ2M13AAA
+
+
+False
+-0.785398163397448
+40
+epHead
+8TqXpAmOBEiEDJ5OcyQ/XQAA
+
+
+False
+0.785398163397448
+40
+epTail
+HJqngn7i40G7I2drQ2M13AAA
+
+
+False
+-1000
+-944
+50
+8
+8TqXpAmOBEiEDJ5OcyQ/XQAA
+
+
+False
+-1000
+-944
+50
+8
+HJqngn7i40G7I2drQ2M13AAA
+
+
+
+clMaroon
+$00B9FFFF
+96
+428
+86
+59
+False
+5zz6gIaMNUKuDMdUeCpo8AAA
+
+
+1
+exclude
+
+
+False
+
+
+False
+
+
+
+5zz6gIaMNUKuDMdUeCpo8AAA
+
+
+False
+5zz6gIaMNUKuDMdUeCpo8AAA
+
+
+False
+5zz6gIaMNUKuDMdUeCpo8AAA
+
+
+
+clMaroon
+$00B9FFFF
+138,428;139,366
++L/IOS7xU0CZQGaUuRo79wAA
+hiEBWGBHwkiFkbHZnmNXjwAA
+1qpBGzzGLEW4skqW8PLQfQAA
+
+False
+1.5707963267949
+15
++L/IOS7xU0CZQGaUuRo79wAA
+
+
+False
+1.5707963267949
+30
++L/IOS7xU0CZQGaUuRo79wAA
+
+
+False
+-1.5707963267949
+15
++L/IOS7xU0CZQGaUuRo79wAA
+
+
+False
+-0.523598775598299
+30
+epHead
+Bb0khctAz0uZw09KLQlAkgAA
+
+
+False
+0.523598775598299
+30
+epTail
+zJtttkdoP0Sbxkekv0oDkgAA
+
+
+False
+0.523598775598299
+25
+epHead
+Bb0khctAz0uZw09KLQlAkgAA
+
+
+-0.966666235847484
+18.0277563773199
+epTail
+0..*
+zJtttkdoP0Sbxkekv0oDkgAA
+
+
+False
+-0.785398163397448
+40
+epHead
+Bb0khctAz0uZw09KLQlAkgAA
+
+
+False
+0.785398163397448
+40
+epTail
+zJtttkdoP0Sbxkekv0oDkgAA
+
+
+False
+-1000
+-944
+50
+8
+Bb0khctAz0uZw09KLQlAkgAA
+
+
+False
+-1000
+-944
+50
+8
+zJtttkdoP0Sbxkekv0oDkgAA
+
+
+
+clMaroon
+$00B9FFFF
+165,428;223,366
+o4nt6mUd0E+mlHL56Zp/egAA
+xIrnHgVLxUm97jUu4dACtAAA
+1qpBGzzGLEW4skqW8PLQfQAA
+
+False
+1.5707963267949
+15
+o4nt6mUd0E+mlHL56Zp/egAA
+
+
+False
+1.5707963267949
+30
+o4nt6mUd0E+mlHL56Zp/egAA
+
+
+False
+-1.5707963267949
+15
+o4nt6mUd0E+mlHL56Zp/egAA
+
+
+False
+-0.523598775598299
+30
+epHead
+i4KhAL0Fx02s74Y8MHfVngAA
+
+
+False
+0.523598775598299
+30
+epTail
+KGcKEMkgh0aSl/cfRzrdIAAA
+
+
+False
+0.523598775598299
+25
+epHead
+i4KhAL0Fx02s74Y8MHfVngAA
+
+
+-0.408591891701127
+25.0798724079689
+epTail
+0..*
+KGcKEMkgh0aSl/cfRzrdIAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+i4KhAL0Fx02s74Y8MHfVngAA
+
+
+False
+0.785398163397448
+40
+epTail
+KGcKEMkgh0aSl/cfRzrdIAAA
+
+
+False
+-1000
+-944
+50
+8
+i4KhAL0Fx02s74Y8MHfVngAA
+
+
+False
+-1000
+-944
+50
+8
+KGcKEMkgh0aSl/cfRzrdIAAA
+
+
+
+
+7
+
+<<content v.2>>
+3q8/Gqy8BE6llPh/zkCQ1QAA
+4
+f8VxW8OVdEC1Ifglf0w3KQAA
+hM4omv6+BUCtvVAq2IpllQAA
+p+5FqB0RkEyMyy7HPlGYUgAA
+avpVwwSPMkK8vsB03T7RdgAA
+2
+rXN+Z0guxUy+Rz7TPELWrwAA
+icqPwTtyj0mQrj/C6I39GgAA
+
+
+output
+3q8/Gqy8BE6llPh/zkCQ1QAA
+4
+VqsyvTGqykGXuB4//e+E1QAA
+pXZ2T88WYkqqLC3C5J5JGQAA
+ogXT3yXsVESLaM9lETp9YgAA
+qlZfSHmkokCz217g75ZeFgAA
+3
+Oz+BmuTcoUOLIBa7KS6DCQAA
+lKnU1zst3E2NB7kzxoZgugAA
+UXpHqpXWWkWaXmnhdMf/GwAA
+3
+
+dir
+0..1
+5zzJFTvUNk2trdiXalmeUQAA
+
+
+flatten
+0..1
+5zzJFTvUNk2trdiXalmeUQAA
+
+
+file
+0..1
+5zzJFTvUNk2trdiXalmeUQAA
+
+
+
+desc
+3q8/Gqy8BE6llPh/zkCQ1QAA
+1
+1b5HAClRfUyRCPe52Vr/SgAA
+
+
+externalinput
+3q8/Gqy8BE6llPh/zkCQ1QAA
+4
+hiEBWGBHwkiFkbHZnmNXjwAA
+a3/Zo5lKO0io0KWOJBoBswAA
+icZ50wwgJEm1Eh73JceQdAAA
+DdjJBPyuZE+3STMvtDaQLgAA
+3
+3UfPK4/xyES+AyWGHmWJsQAA
+8TqXpAmOBEiEDJ5OcyQ/XQAA
+Bb0khctAz0uZw09KLQlAkgAA
+2
+
+dir
+0..1
+ivlA8JWOIEOE/0Z2gIiUMAAA
+
+
+file
+0..1
+ivlA8JWOIEOE/0Z2gIiUMAAA
+
+
+
+input
+3q8/Gqy8BE6llPh/zkCQ1QAA
+4
+xIrnHgVLxUm97jUu4dACtAAA
+FJL7VBgksUqf+mJgiwAJEgAA
+rnfjw1R4i0K4tZwRBQQpZwAA
+Fr1gW265/EygPEwH23p21QAA
+3
+nckaYJRIc0C6lCvSiTPB3gAA
+KX2YnwUuo0G17Q+mXzzS2wAA
+i4KhAL0Fx02s74Y8MHfVngAA
+2
+
+dir
+0..1
+RSfNCw5wNUGCDOhEi/bCrwAA
+
+
+file
+0..1
+RSfNCw5wNUGCDOhEi/bCrwAA
+
+
+
+include
+3q8/Gqy8BE6llPh/zkCQ1QAA
+4
+Ge7hwnTE00+T03ai+/7E4QAA
+7i9IofoLd0SQ8bvL01zEVwAA
+zVMOY5mMX0KTQyrEkrJ9OAAA
+i07nfUkJU0CKLIX0bOJ/tgAA
+2
+Lezmq5MfFEew6znmWvrvMAAA
+HJqngn7i40G7I2drQ2M13AAA
+2
+
+pattern
+0..1
+RR0EuzZlckCzW5H+HzADZAAA
+
+
+files
+0..1
+RR0EuzZlckCzW5H+HzADZAAA
+
+
+
+exclude
+3q8/Gqy8BE6llPh/zkCQ1QAA
+4
+1qpBGzzGLEW4skqW8PLQfQAA
+uvFIM8khYkCOy0etwshVqwAA
+7gPI8oW6sE+H2SdMYjie0gAA
+BOTUOx3bo0qWbgyekPr3kAAA
+2
+zJtttkdoP0Sbxkekv0oDkgAA
+KGcKEMkgh0aSl/cfRzrdIAAA
+2
+
+pattern
+0..1
+5zz6gIaMNUKuDMdUeCpo8AAA
+
+
+files
+0..1
+5zz6gIaMNUKuDMdUeCpo8AAA
+
+
+
+
+crml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+crml
+qGZtK480D0mYNBVDpwOmTQAA
+
+lHoPttW5gkeXVIETRYHrUgAA
+14
+
+clMaroon
+$00B9FFFF
+188
+28
+134
+111
+False
+False
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+1
+repository
+
+
+False
+
+
+False
+
+
+
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+False
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+False
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+
+clMaroon
+$00B9FFFF
+44
+244
+86
+111
+False
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+1
+key
+
+
+False
+
+
+False
+
+
+
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+False
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+False
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+
+clMaroon
+$00B9FFFF
+129,244;211,138
+T6dZEmqJBk+JCBjNk+rKTgAA
++nwbLtWGLU+Hz+YSIaPSPgAA
+5EaYUrSobEeRZVmpVQKv3QAA
+
+False
+1.5707963267949
+15
+T6dZEmqJBk+JCBjNk+rKTgAA
+
+
+False
+1.5707963267949
+30
+T6dZEmqJBk+JCBjNk+rKTgAA
+
+
+False
+-1.5707963267949
+15
+T6dZEmqJBk+JCBjNk+rKTgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+IlupvcREqU63XTFypXGQ7gAA
+
+
+False
+0.523598775598299
+30
+epTail
+iLAuQHEQv06jzD7kiYoXuAAA
+
+
+False
+0.523598775598299
+25
+epHead
+IlupvcREqU63XTFypXGQ7gAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+iLAuQHEQv06jzD7kiYoXuAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+IlupvcREqU63XTFypXGQ7gAA
+
+
+False
+0.785398163397448
+40
+epTail
+iLAuQHEQv06jzD7kiYoXuAAA
+
+
+False
+-1308
+-1196
+50
+8
+IlupvcREqU63XTFypXGQ7gAA
+
+
+False
+-1308
+-1196
+50
+8
+iLAuQHEQv06jzD7kiYoXuAAA
+
+
+
+clMaroon
+$00B9FFFF
+24
+444
+80
+59
+False
+owewdd03PEqMInhVg8hxegAA
+
+
+1
+bit
+
+
+False
+
+
+False
+
+
+
+owewdd03PEqMInhVg8hxegAA
+
+
+False
+owewdd03PEqMInhVg8hxegAA
+
+
+False
+owewdd03PEqMInhVg8hxegAA
+
+
+
+clMaroon
+$00B9FFFF
+67,444;79,354
+bp+wZYcgB06p/FXxYnPeTwAA
+5EaYUrSobEeRZVmpVQKv3QAA
+VpBGGuW55UySrLIkovhGCAAA
+
+False
+1.5707963267949
+15
+bp+wZYcgB06p/FXxYnPeTwAA
+
+
+False
+1.5707963267949
+30
+bp+wZYcgB06p/FXxYnPeTwAA
+
+
+False
+-1.5707963267949
+15
+bp+wZYcgB06p/FXxYnPeTwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+GHXyLRfe2keijGBsIZEejAAA
+
+
+False
+0.523598775598299
+30
+epTail
+HhbIwX8GCEqzk5wgVXMRVwAA
+
+
+False
+0.523598775598299
+25
+epHead
+GHXyLRfe2keijGBsIZEejAAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+HhbIwX8GCEqzk5wgVXMRVwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+GHXyLRfe2keijGBsIZEejAAA
+
+
+False
+0.785398163397448
+40
+epTail
+HhbIwX8GCEqzk5wgVXMRVwAA
+
+
+False
+-1308
+-1196
+50
+8
+GHXyLRfe2keijGBsIZEejAAA
+
+
+False
+-1308
+-1196
+50
+8
+HhbIwX8GCEqzk5wgVXMRVwAA
+
+
+
+clMaroon
+$00B9FFFF
+224
+204
+80
+72
+False
+RH51ga45KE6KDoeLQE8QlQAA
+
+
+1
+access
+
+
+False
+
+
+False
+
+
+
+RH51ga45KE6KDoeLQE8QlQAA
+
+
+False
+RH51ga45KE6KDoeLQE8QlQAA
+
+
+False
+RH51ga45KE6KDoeLQE8QlQAA
+
+
+
+clMaroon
+$00B9FFFF
+261,204;257,138
+kRhs7Db07UCnVGvTeUn8qgAA
++nwbLtWGLU+Hz+YSIaPSPgAA
+cJgk6WhGO0avPyOwTnu1cwAA
+
+False
+1.5707963267949
+15
+kRhs7Db07UCnVGvTeUn8qgAA
+
+
+False
+1.5707963267949
+30
+kRhs7Db07UCnVGvTeUn8qgAA
+
+
+False
+-1.5707963267949
+15
+kRhs7Db07UCnVGvTeUn8qgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+pX9DIVuaOEuVu+1aJ6TVBwAA
+
+
+False
+0.523598775598299
+30
+epTail
+bgAX+775K0+IdCitgl+l0gAA
+
+
+False
+0.523598775598299
+25
+epHead
+pX9DIVuaOEuVu+1aJ6TVBwAA
+
+
+-0.523598775598299
+25
+epTail
+0..2
+bgAX+775K0+IdCitgl+l0gAA
+
+
+False
+-0.785398163397448
+40
+epHead
+pX9DIVuaOEuVu+1aJ6TVBwAA
+
+
+False
+0.785398163397448
+40
+epTail
+bgAX+775K0+IdCitgl+l0gAA
+
+
+False
+-1308
+-1196
+50
+8
+pX9DIVuaOEuVu+1aJ6TVBwAA
+
+
+False
+-1308
+-1196
+50
+8
+bgAX+775K0+IdCitgl+l0gAA
+
+
+
+clMaroon
+$00B9FFFF
+120
+436
+101
+72
+False
+eYGzjuCMLkKn4NjB0dEn0AAA
+
+
+1
+value
+
+
+False
+
+
+False
+
+
+
+eYGzjuCMLkKn4NjB0dEn0AAA
+
+
+False
+eYGzjuCMLkKn4NjB0dEn0AAA
+
+
+False
+eYGzjuCMLkKn4NjB0dEn0AAA
+
+
+
+clMaroon
+$00B9FFFF
+424
+232
+90
+150
+False
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+1
+keyRange
+
+
+False
+
+
+False
+
+
+
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+False
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+False
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+
+clMaroon
+$00B9FFFF
+424,260;307,138
+eb3ayVr/ukqo6hvbKDz/swAA
++nwbLtWGLU+Hz+YSIaPSPgAA
+NbmAtWNEy0uviAWASDmMxAAA
+
+False
+1.5707963267949
+15
+eb3ayVr/ukqo6hvbKDz/swAA
+
+
+False
+1.5707963267949
+30
+eb3ayVr/ukqo6hvbKDz/swAA
+
+
+False
+-1.5707963267949
+15
+eb3ayVr/ukqo6hvbKDz/swAA
+
+
+False
+-0.523598775598299
+30
+epHead
+7c4AqBkyEUiX8qdLBY9+IQAA
+
+
+False
+0.523598775598299
+30
+epTail
+YPoJAT5z60mJJ/4nlVKgQwAA
+
+
+False
+0.523598775598299
+25
+epHead
+7c4AqBkyEUiX8qdLBY9+IQAA
+
+
+0.551133160098852
+23.7697286480094
+epTail
+0..*
+YPoJAT5z60mJJ/4nlVKgQwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+7c4AqBkyEUiX8qdLBY9+IQAA
+
+
+False
+0.785398163397448
+40
+epTail
+YPoJAT5z60mJJ/4nlVKgQwAA
+
+
+False
+-1308
+-1196
+50
+8
+7c4AqBkyEUiX8qdLBY9+IQAA
+
+
+False
+-1308
+-1196
+50
+8
+YPoJAT5z60mJJ/4nlVKgQwAA
+
+
+
+clMaroon
+$00B9FFFF
+303,252;424,292
+uqzj6Tgi3UqwZ2fIPCUxxgAA
+NbmAtWNEy0uviAWASDmMxAAA
+cJgk6WhGO0avPyOwTnu1cwAA
+
+False
+1.5707963267949
+15
+uqzj6Tgi3UqwZ2fIPCUxxgAA
+
+
+False
+1.5707963267949
+30
+uqzj6Tgi3UqwZ2fIPCUxxgAA
+
+
+False
+-1.5707963267949
+15
+uqzj6Tgi3UqwZ2fIPCUxxgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+YCmqDh6mYEC2sMTiRqfJhgAA
+
+
+False
+0.523598775598299
+30
+epTail
++0..2
+cma9bSbXZku+M+oWkso1HAAA
+
+
+False
+0.523598775598299
+25
+epHead
+YCmqDh6mYEC2sMTiRqfJhgAA
+
+
+-0.523598775598299
+25
+epTail
+0..2
+cma9bSbXZku+M+oWkso1HAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+YCmqDh6mYEC2sMTiRqfJhgAA
+
+
+False
+0.785398163397448
+40
+epTail
+cma9bSbXZku+M+oWkso1HAAA
+
+
+False
+-1308
+-1196
+50
+8
+YCmqDh6mYEC2sMTiRqfJhgAA
+
+
+False
+-1308
+-1196
+50
+8
+cma9bSbXZku+M+oWkso1HAAA
+
+
+
+clMaroon
+$00B9FFFF
+224,252;129,284
+kXQY/Vx23UC1DCh8F9IRdQAA
+5EaYUrSobEeRZVmpVQKv3QAA
+cJgk6WhGO0avPyOwTnu1cwAA
+
+False
+1.5707963267949
+15
+kXQY/Vx23UC1DCh8F9IRdQAA
+
+
+False
+1.5707963267949
+30
+kXQY/Vx23UC1DCh8F9IRdQAA
+
+
+False
+-1.5707963267949
+15
+kXQY/Vx23UC1DCh8F9IRdQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+vvpTBHVSakeBGaqd5bC6mwAA
+
+
+False
+0.523598775598299
+30
+epTail
+eJrRdjRApEijUlwTFcnU6QAA
+
+
+False
+0.523598775598299
+25
+epHead
+vvpTBHVSakeBGaqd5bC6mwAA
+
+
+-0.523598775598299
+25
+epTail
+0..2
+eJrRdjRApEijUlwTFcnU6QAA
+
+
+False
+-0.785398163397448
+40
+epHead
+vvpTBHVSakeBGaqd5bC6mwAA
+
+
+False
+0.785398163397448
+40
+epTail
+eJrRdjRApEijUlwTFcnU6QAA
+
+
+False
+-1308
+-1196
+50
+8
+vvpTBHVSakeBGaqd5bC6mwAA
+
+
+False
+-1308
+-1196
+50
+8
+eJrRdjRApEijUlwTFcnU6QAA
+
+
+
+clMaroon
+$00B9FFFF
+129,300;424,305
+i+idGeRyH0O6Trx2aQWMcwAA
+NbmAtWNEy0uviAWASDmMxAAA
+5EaYUrSobEeRZVmpVQKv3QAA
+
+False
+1.5707963267949
+15
+i+idGeRyH0O6Trx2aQWMcwAA
+
+
+False
+1.5707963267949
+30
+i+idGeRyH0O6Trx2aQWMcwAA
+
+
+False
+-1.5707963267949
+15
+i+idGeRyH0O6Trx2aQWMcwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+RfAdcCNofE+evhlZyty3cgAA
+
+
+False
+0.523598775598299
+30
+epTail
+c/1XK8730064TYgqeMtY+wAA
+
+
+False
+0.523598775598299
+25
+epHead
+RfAdcCNofE+evhlZyty3cgAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+c/1XK8730064TYgqeMtY+wAA
+
+
+False
+-0.785398163397448
+40
+epHead
+RfAdcCNofE+evhlZyty3cgAA
+
+
+False
+0.785398163397448
+40
+epTail
+c/1XK8730064TYgqeMtY+wAA
+
+
+False
+-1308
+-1196
+50
+8
+RfAdcCNofE+evhlZyty3cgAA
+
+
+False
+-1308
+-1196
+50
+8
+c/1XK8730064TYgqeMtY+wAA
+
+
+
+clMaroon
+$00B9FFFF
+153,436;113,354
+POwBB4/GAUeNaKKEcJpIlQAA
+5EaYUrSobEeRZVmpVQKv3QAA
+BtR16XQRokCb/cA1/inx8gAA
+
+False
+1.5707963267949
+15
+POwBB4/GAUeNaKKEcJpIlQAA
+
+
+False
+1.5707963267949
+30
+POwBB4/GAUeNaKKEcJpIlQAA
+
+
+False
+-1.5707963267949
+15
+POwBB4/GAUeNaKKEcJpIlQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+ZEDi//IT4ESS+61ttQt0ZQAA
+
+
+False
+0.523598775598299
+30
+epTail
+/F1D5wzLBE2wKfdscOPvswAA
+
+
+False
+0.523598775598299
+25
+epHead
+ZEDi//IT4ESS+61ttQt0ZQAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+/F1D5wzLBE2wKfdscOPvswAA
+
+
+False
+-0.785398163397448
+40
+epHead
+ZEDi//IT4ESS+61ttQt0ZQAA
+
+
+False
+0.785398163397448
+40
+epTail
+/F1D5wzLBE2wKfdscOPvswAA
+
+
+False
+-1308
+-1196
+50
+8
+ZEDi//IT4ESS+61ttQt0ZQAA
+
+
+False
+-1308
+-1196
+50
+8
+/F1D5wzLBE2wKfdscOPvswAA
+
+
+
+
+6
+
+repository
+qGZtK480D0mYNBVDpwOmTQAA
+4
++nwbLtWGLU+Hz+YSIaPSPgAA
+UizWMh4VkEmN+kftLvxc/gAA
+VSWdlssMk0aMasrpCwCJOwAA
+AWD09lz0YUmnV4QV1eOY1wAA
+3
+IlupvcREqU63XTFypXGQ7gAA
+pX9DIVuaOEuVu+1aJ6TVBwAA
+7c4AqBkyEUiX8qdLBY9+IQAA
+6
+
+version
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+uidName
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+uidValue
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+initialialisationFileVersion
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+owner
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+backup
+bsLMfNcnMUOLwcGU0WrbswAA
+
+
+
+key
+qGZtK480D0mYNBVDpwOmTQAA
+4
+5EaYUrSobEeRZVmpVQKv3QAA
+dXGVOm9nmEy/KTy5FcmCTQAA
+/AmPM8keC0uf3yV0kWnKNgAA
+DkQ0l+BmBk+D/XNNYw8QJwAA
+5
+iLAuQHEQv06jzD7kiYoXuAAA
+GHXyLRfe2keijGBsIZEejAAA
+vvpTBHVSakeBGaqd5bC6mwAA
+ZEDi//IT4ESS+61ttQt0ZQAA
+c/1XK8730064TYgqeMtY+wAA
+6
+
+name
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+int
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+type
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+ref
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+readOnly
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+backup
+8qRD67PVK0aWXk0wa4g0EAAA
+
+
+
+access
+qGZtK480D0mYNBVDpwOmTQAA
+4
+cJgk6WhGO0avPyOwTnu1cwAA
+wUthsVEsoEKYXTCCIeYGAwAA
+8douAJiqj0easJyFlmL3iAAA
+2ac7MKCI8UOB0WqZZooLRQAA
+3
+bgAX+775K0+IdCitgl+l0gAA
+cma9bSbXZku+M+oWkso1HAAA
+eJrRdjRApEijUlwTFcnU6QAA
+3
+
+capabilities
+RH51ga45KE6KDoeLQE8QlQAA
+
+
+type
+RH51ga45KE6KDoeLQE8QlQAA
+
+
+sid
+RH51ga45KE6KDoeLQE8QlQAA
+
+
+
+bit
+qGZtK480D0mYNBVDpwOmTQAA
+4
+VpBGGuW55UySrLIkovhGCAAA
+T+oMueN60k2jocvQkL7/bgAA
+OV3DMJJtlkSHWbQ6B/2QpAAA
+KpcFJEB1zUuPKUwPp8ZoeQAA
+1
+HhbIwX8GCEqzk5wgVXMRVwAA
+2
+
+ref
+owewdd03PEqMInhVg8hxegAA
+
+
+value
+owewdd03PEqMInhVg8hxegAA
+
+
+
+value
+qGZtK480D0mYNBVDpwOmTQAA
+4
+BtR16XQRokCb/cA1/inx8gAA
+/QlnnLPpk0K4LIQGtgPlMQAA
+bDTplzAAnU+yd8NRbba4ggAA
+lQIsiurv6U61NSrIl6xDZgAA
+1
+/F1D5wzLBE2wKfdscOPvswAA
+3
+
+value
+eYGzjuCMLkKn4NjB0dEn0AAA
+
+
+name
+eYGzjuCMLkKn4NjB0dEn0AAA
+
+
+desc
+eYGzjuCMLkKn4NjB0dEn0AAA
+
+
+
+keyRange
+qGZtK480D0mYNBVDpwOmTQAA
+4
+NbmAtWNEy0uviAWASDmMxAAA
+oe3w5nWFLkOEF0x7esL3gwAA
+wHXSmfvk3EicS65WwlHwngAA
++Ui3b2tC0kuC4O21ierDQgAA
+3
+YPoJAT5z60mJJ/4nlVKgQwAA
+YCmqDh6mYEC2sMTiRqfJhgAA
+RfAdcCNofE+evhlZyty3cgAA
+9
+
+name
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+firstInt
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+lastInt
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+indexBits
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+firstIndex
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+countInt
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+ref
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+readOnly
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+backup
+LyqVpBJycU+8Cyr2qe1BvAAA
+
+
+
+
+ruleml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+ruleml
+W9oh7yos/U2flTVaR6jCYQAA
+
+Qb0bMw3xFkm+c/jyw9QK/gAA
+5
+
+clMaroon
+$00B9FFFF
+264
+124
+105
+46
+False
+tPNexD/wZ0Kui7rS13cHiQAA
+
+
+1
+eval_globals
+
+
+False
+
+
+False
+
+
+
+tPNexD/wZ0Kui7rS13cHiQAA
+
+
+False
+tPNexD/wZ0Kui7rS13cHiQAA
+
+
+False
+tPNexD/wZ0Kui7rS13cHiQAA
+
+
+
+clMaroon
+$00B9FFFF
+152
+124
+90
+30
+1UxBGcFK3EKPBFhSfrqD/gAA
+
+
+1
+rule
+
+
+False
+
+
+False
+
+
+
+False
+1UxBGcFK3EKPBFhSfrqD/gAA
+
+
+False
+1UxBGcFK3EKPBFhSfrqD/gAA
+
+
+False
+1UxBGcFK3EKPBFhSfrqD/gAA
+
+
+
+clMaroon
+$00B9FFFF
+208
+36
+86
+30
+Zb0aDQhc/0+9cFTqn86nzAAA
+
+
+1
+<<ruleml>>
+
+
+False
+
+
+False
+
+
+
+False
+Zb0aDQhc/0+9cFTqn86nzAAA
+
+
+False
+Zb0aDQhc/0+9cFTqn86nzAAA
+
+
+False
+Zb0aDQhc/0+9cFTqn86nzAAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+224,124;224,65
+VBvmUm8cYUO9N+N5odPPwgAA
+m31f7bq1D0GmhHHoFyocMgAA
+6xgTZ7FpWUWAaKkd9yGFOAAA
+
+False
+1.5707963267949
+15
+VBvmUm8cYUO9N+N5odPPwgAA
+
+
+False
+1.5707963267949
+30
+VBvmUm8cYUO9N+N5odPPwgAA
+
+
+False
+-1.5707963267949
+15
+VBvmUm8cYUO9N+N5odPPwgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+3BfCAZv/iUS90Qjw30LrDwAA
+
+
+False
+0.523598775598299
+30
+epTail
+atPDiS9SkUuVO8zUd1za/gAA
+
+
+False
+0.523598775598299
+25
+epHead
+3BfCAZv/iUS90Qjw30LrDwAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+atPDiS9SkUuVO8zUd1za/gAA
+
+
+False
+-0.785398163397448
+40
+epHead
+3BfCAZv/iUS90Qjw30LrDwAA
+
+
+False
+0.785398163397448
+40
+epTail
+atPDiS9SkUuVO8zUd1za/gAA
+
+
+False
+-1000
+-1000
+50
+8
+3BfCAZv/iUS90Qjw30LrDwAA
+
+
+False
+-1000
+-1000
+50
+8
+atPDiS9SkUuVO8zUd1za/gAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+280,124;280,65
+Xyq6xieNl0Cn5MPsr7wH4gAA
+m31f7bq1D0GmhHHoFyocMgAA
+dyXXZnwue02hiPSfuW8khAAA
+
+False
+1.5707963267949
+15
+Xyq6xieNl0Cn5MPsr7wH4gAA
+
+
+False
+1.5707963267949
+30
+Xyq6xieNl0Cn5MPsr7wH4gAA
+
+
+False
+-1.5707963267949
+15
+Xyq6xieNl0Cn5MPsr7wH4gAA
+
+
+False
+-0.523598775598299
+30
+epHead
+17kbByDKYUyZ+m2wpPWaxgAA
+
+
+False
+0.523598775598299
+30
+epTail
+b2WodVCgbkarRKGvRfujywAA
+
+
+False
+0.523598775598299
+25
+epHead
+17kbByDKYUyZ+m2wpPWaxgAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+b2WodVCgbkarRKGvRfujywAA
+
+
+False
+-0.785398163397448
+40
+epHead
+17kbByDKYUyZ+m2wpPWaxgAA
+
+
+False
+0.785398163397448
+40
+epTail
+b2WodVCgbkarRKGvRfujywAA
+
+
+False
+-1000
+-1000
+50
+8
+17kbByDKYUyZ+m2wpPWaxgAA
+
+
+False
+-1000
+-1000
+50
+8
+b2WodVCgbkarRKGvRfujywAA
+
+
+
+
+3
+
+<<ruleml>>
+W9oh7yos/U2flTVaR6jCYQAA
+4
+m31f7bq1D0GmhHHoFyocMgAA
+9Jix+EFpNEeQwrtd6FtreAAA
+karUmOGlDUGWg1fLA4xncgAA
+k4/35kxCtUOzOETdRAt8ZgAA
+2
+3BfCAZv/iUS90Qjw30LrDwAA
+17kbByDKYUyZ+m2wpPWaxgAA
+
+
+rule
+W9oh7yos/U2flTVaR6jCYQAA
+4
+6xgTZ7FpWUWAaKkd9yGFOAAA
+WdjwZH85+UKt546ACmpSUwAA
+QBcb/+4Zt0C9KGOho0itEgAA
+yBCZtO71ykyejq6twf3sJwAA
+1
+atPDiS9SkUuVO8zUd1za/gAA
+
+
+eval_globals
+W9oh7yos/U2flTVaR6jCYQAA
+4
+dyXXZnwue02hiPSfuW8khAAA
+reFnGrjcmUmvbgNWcMLchgAA
+QAL5BcfilkiGMFwc1FqX9QAA
+sBNYasn4h0ShnAVtLQkrfwAA
+1
+b2WodVCgbkarRKGvRfujywAA
+1
+
+file
+0..1
+tPNexD/wZ0Kui7rS13cHiQAA
+
+
+
+
+implml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+implml
+nunAvzsMpEeElylKkdpPBgAA
+
+Qj8LTG3bgE6FmHTG1v3Y+gAA
+19
+
+clMaroon
+$00B9FFFF
+368
+457
+103
+69
+False
+DEez7Bc9Uk2h44eLm4tOTAAA
+
+
+1
+tag
+
+
+False
+
+
+False
+
+
+
+DEez7Bc9Uk2h44eLm4tOTAAA
+
+
+False
+DEez7Bc9Uk2h44eLm4tOTAAA
+
+
+False
+DEez7Bc9Uk2h44eLm4tOTAAA
+
+
+
+clMaroon
+$00B9FFFF
+216
+232
+137
+43
+zjzhCfIGK0Ooz0gx49BvDwAA
+
+
+1
+
+
+<<implml file>>
+
+
+False
+
+
+
+False
+zjzhCfIGK0Ooz0gx49BvDwAA
+
+
+False
+zjzhCfIGK0Ooz0gx49BvDwAA
+
+
+False
+zjzhCfIGK0Ooz0gx49BvDwAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+424,457;424,436;452,436;452,400
+bgc8Y2rnekGMLllh30J1OQAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+fFUPdkT+cECZRPlQsVRNmgAA
+
+False
+1.5707963267949
+15
+bgc8Y2rnekGMLllh30J1OQAA
+
+
+False
+1.5707963267949
+30
+bgc8Y2rnekGMLllh30J1OQAA
+
+
+False
+-1.5707963267949
+15
+bgc8Y2rnekGMLllh30J1OQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+aULbbut4DECnPwmgTtTx2gAA
+
+
+False
+0.523598775598299
+30
+epTail
+Q4SS4jSQ20i54ioZw+85jQAA
+
+
+False
+0.523598775598299
+25
+epHead
+aULbbut4DECnPwmgTtTx2gAA
+
+
+-5.34741517464291
+23.6008474424119
+epTail
+0..*
+Q4SS4jSQ20i54ioZw+85jQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+aULbbut4DECnPwmgTtTx2gAA
+
+
+False
+0.785398163397448
+40
+epTail
+Q4SS4jSQ20i54ioZw+85jQAA
+
+
+False
+-808
+-652
+50
+8
+aULbbut4DECnPwmgTtTx2gAA
+
+
+False
+-808
+-652
+50
+8
+Q4SS4jSQ20i54ioZw+85jQAA
+
+
+
+clMaroon
+$00B9FFFF
+480
+457
+145
+46
+False
+A9TZ2/XE7UqgiiSvVEDLQwAA
+
+
+1
+phase
+
+
+False
+
+
+False
+
+
+
+A9TZ2/XE7UqgiiSvVEDLQwAA
+
+
+False
+A9TZ2/XE7UqgiiSvVEDLQwAA
+
+
+False
+A9TZ2/XE7UqgiiSvVEDLQwAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+520,457;520,436;452,436;452,400
+xX7RE0ASlkOrRf9dOxH/zgAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+N8ckb8OYP0SfE9Y3pFPHeQAA
+
+False
+1.5707963267949
+15
+xX7RE0ASlkOrRf9dOxH/zgAA
+
+
+False
+1.5707963267949
+30
+xX7RE0ASlkOrRf9dOxH/zgAA
+
+
+False
+-1.5707963267949
+15
+xX7RE0ASlkOrRf9dOxH/zgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+eXkeLjSvuU6MRxUlhWndcAAA
+
+
+False
+0.523598775598299
+30
+epTail
+mWEP+8jbjE24hKhlVCG8uQAA
+
+
+False
+0.523598775598299
+25
+epHead
+eXkeLjSvuU6MRxUlhWndcAAA
+
+
+-0.750928942501882
+20.5182845286832
+epTail
+0..1
+mWEP+8jbjE24hKhlVCG8uQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+eXkeLjSvuU6MRxUlhWndcAAA
+
+
+False
+0.785398163397448
+40
+epTail
+mWEP+8jbjE24hKhlVCG8uQAA
+
+
+False
+-808
+-652
+50
+8
+eXkeLjSvuU6MRxUlhWndcAAA
+
+
+False
+-808
+-652
+50
+8
+mWEP+8jbjE24hKhlVCG8uQAA
+
+
+
+clMaroon
+$00B9FFFF
+272
+320
+82
+72
+False
+hEercfKAykep6GRNpygwAAAA
+
+
+1
+tempfeature
+
+
+False
+
+
+False
+
+
+
+hEercfKAykep6GRNpygwAAAA
+
+
+False
+hEercfKAykep6GRNpygwAAAA
+
+
+False
+hEercfKAykep6GRNpygwAAAA
+
+
+
+clMaroon
+$00B9FFFF
+244
+457
+102
+56
+False
+MuE9xXdvYEODEr1y4vsX9QAA
+
+
+1
+tempseqfeature
+
+
+False
+
+
+False
+
+
+
+MuE9xXdvYEODEr1y4vsX9QAA
+
+
+False
+MuE9xXdvYEODEr1y4vsX9QAA
+
+
+False
+MuE9xXdvYEODEr1y4vsX9QAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+353,363;432,363
+ACScvSJbSEqRvLIQ0IWV9AAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+q4XlSDOPYU+NPe527blyDAAA
+
+False
+1.5707963267949
+15
+ACScvSJbSEqRvLIQ0IWV9AAA
+
+
+False
+1.5707963267949
+30
+ACScvSJbSEqRvLIQ0IWV9AAA
+
+
+False
+-1.5707963267949
+15
+ACScvSJbSEqRvLIQ0IWV9AAA
+
+
+False
+-0.523598775598299
+30
+epHead
+ABzc1o7mCkiMBst076lYvAAA
+
+
+False
+0.523598775598299
+30
+epTail
+MU/1J6u8VEukQZBFAc2A2QAA
+
+
+False
+0.523598775598299
+25
+epHead
+ABzc1o7mCkiMBst076lYvAAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+MU/1J6u8VEukQZBFAc2A2QAA
+
+
+False
+-0.785398163397448
+40
+epHead
+ABzc1o7mCkiMBst076lYvAAA
+
+
+False
+0.785398163397448
+40
+epTail
+MU/1J6u8VEukQZBFAc2A2QAA
+
+
+False
+-792
+-652
+50
+8
+ABzc1o7mCkiMBst076lYvAAA
+
+
+False
+-792
+-652
+50
+8
+MU/1J6u8VEukQZBFAc2A2QAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+345,457;345,436;452,436;452,400
+DefM64TTyU2ZcEZyZ7rTnQAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+EQYzSHCrWUaPx/wRaFPzOwAA
+
+False
+1.5707963267949
+15
+DefM64TTyU2ZcEZyZ7rTnQAA
+
+
+False
+1.5707963267949
+30
+DefM64TTyU2ZcEZyZ7rTnQAA
+
+
+False
+-1.5707963267949
+15
+DefM64TTyU2ZcEZyZ7rTnQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+5lW8exzmFUirT6PzXp05/AAA
+
+
+False
+0.523598775598299
+30
+epTail
+xx3gzV5BjUSwJg5lsak/CgAA
+
+
+False
+0.523598775598299
+25
+epHead
+5lW8exzmFUirT6PzXp05/AAA
+
+
+-5.45433553370487
+16.2788205960997
+epTail
+0..*
+xx3gzV5BjUSwJg5lsak/CgAA
+
+
+False
+-0.785398163397448
+40
+epHead
+5lW8exzmFUirT6PzXp05/AAA
+
+
+False
+0.785398163397448
+40
+epTail
+xx3gzV5BjUSwJg5lsak/CgAA
+
+
+False
+-808
+-652
+50
+8
+5lW8exzmFUirT6PzXp05/AAA
+
+
+False
+-808
+-652
+50
+8
+xx3gzV5BjUSwJg5lsak/CgAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+308,391;308,457
+XoJDBeddjkqF9PVLMr+HVgAA
+EQYzSHCrWUaPx/wRaFPzOwAA
+q4XlSDOPYU+NPe527blyDAAA
+
+False
+1.5707963267949
+15
+XoJDBeddjkqF9PVLMr+HVgAA
+
+
+False
+1.5707963267949
+30
+XoJDBeddjkqF9PVLMr+HVgAA
+
+
+False
+-1.5707963267949
+15
+XoJDBeddjkqF9PVLMr+HVgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+uIda2Q00s0uCEjYvkFMChwAA
+
+
+False
+0.523598775598299
+30
+epTail
+ePQ/2OtUrky7xn80sS850gAA
+
+
+False
+0.523598775598299
+25
+epHead
+uIda2Q00s0uCEjYvkFMChwAA
+
+
+-1.07685413469956
+14.7648230602334
+epTail
+0..*
+ePQ/2OtUrky7xn80sS850gAA
+
+
+False
+-0.785398163397448
+40
+epHead
+uIda2Q00s0uCEjYvkFMChwAA
+
+
+False
+0.785398163397448
+40
+epTail
+ePQ/2OtUrky7xn80sS850gAA
+
+
+False
+-808
+-652
+50
+8
+uIda2Q00s0uCEjYvkFMChwAA
+
+
+False
+-808
+-652
+50
+8
+ePQ/2OtUrky7xn80sS850gAA
+
+
+
+clMaroon
+$00B9FFFF
+432
+332
+80
+69
+QHug9JDMF0eIdhAMRc3BlwAA
+
+
+1
+container
+
+
+False
+
+
+False
+
+
+
+QHug9JDMF0eIdhAMRc3BlwAA
+
+
+QHug9JDMF0eIdhAMRc3BlwAA
+
+
+False
+QHug9JDMF0eIdhAMRc3BlwAA
+
+
+
+clMaroon
+$00B9FFFF
+319,274;432,342
+fOjqr0wnzEqQV2QbncXRyAAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+t73r2IX7MECggYesswXDJAAA
+
+False
+1.5707963267949
+15
+fOjqr0wnzEqQV2QbncXRyAAA
+
+
+False
+1.5707963267949
+30
+fOjqr0wnzEqQV2QbncXRyAAA
+
+
+False
+-1.5707963267949
+15
+fOjqr0wnzEqQV2QbncXRyAAA
+
+
+False
+-0.523598775598299
+30
+epHead
+A/HqW/8oKkubU3VPXj3eWQAA
+
+
+False
+0.523598775598299
+30
+epTail
+3frzsw0XSEq7O8j/X125ewAA
+
+
+-5.35162832296677
+15.6204993518133
+epHead
+1
+A/HqW/8oKkubU3VPXj3eWQAA
+
+
+-0.99615158422557
+16.1245154965971
+epTail
+1
+3frzsw0XSEq7O8j/X125ewAA
+
+
+False
+-0.785398163397448
+40
+epHead
+A/HqW/8oKkubU3VPXj3eWQAA
+
+
+False
+0.785398163397448
+40
+epTail
+3frzsw0XSEq7O8j/X125ewAA
+
+
+False
+-928
+-764
+50
+8
+A/HqW/8oKkubU3VPXj3eWQAA
+
+
+False
+-928
+-764
+50
+8
+3frzsw0XSEq7O8j/X125ewAA
+
+
+
+clMaroon
+$00B9FFFF
+440
+220
+61
+45
+sdkIcon
+IONricIIR0WGo59WsXpFtgAA
+
+
+1
+implbase
+
+
+False
+
+
+False
+
+
+
+False
+IONricIIR0WGo59WsXpFtgAA
+
+
+False
+IONricIIR0WGo59WsXpFtgAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+470,332;470,264
+taqNNc4Me0uannQ7Vlc89gAA
+nsTcPUP9yEKZ2Ue56O4iCAAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+
+False
+1.5707963267949
+15
+taqNNc4Me0uannQ7Vlc89gAA
+
+
+False
+1.5707963267949
+30
+taqNNc4Me0uannQ7Vlc89gAA
+
+
+False
+-1.5707963267949
+15
+taqNNc4Me0uannQ7Vlc89gAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+500,241;564,241;564,360;511,360
+zYO7Oxc95E6KdcR2XpasaAAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+nsTcPUP9yEKZ2Ue56O4iCAAA
+
+False
+1.5707963267949
+15
+zYO7Oxc95E6KdcR2XpasaAAA
+
+
+False
+1.5707963267949
+30
+zYO7Oxc95E6KdcR2XpasaAAA
+
+
+False
+-1.5707963267949
+15
+zYO7Oxc95E6KdcR2XpasaAAA
+
+
+False
+-0.523598775598299
+30
+epHead
+MhZygEis/U2M0wvtfV4YYQAA
+
+
+False
+0.523598775598299
+30
+epTail
+LIobfyFbwUOnOz751BxBWAAA
+
+
+1.55119089793615
+102.019605958855
+epHead
+0..*
+MhZygEis/U2M0wvtfV4YYQAA
+
+
+False
+-0.523598775598299
+25
+epTail
+LIobfyFbwUOnOz751BxBWAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+MhZygEis/U2M0wvtfV4YYQAA
+
+
+False
+0.785398163397448
+40
+epTail
+LIobfyFbwUOnOz751BxBWAAA
+
+
+False
+-1000
+-1000
+50
+8
+MhZygEis/U2M0wvtfV4YYQAA
+
+
+False
+-1000
+-1000
+50
+8
+LIobfyFbwUOnOz751BxBWAAA
+
+
+
+clMaroon
+$00B9FFFF
+632
+457
+91
+56
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+1
+outputSubDir
+
+
+False
+
+
+False
+
+
+
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+False
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+
+clMaroon
+$00B9FFFF
+736
+457
+91
+56
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+1
+outputSubDir
+
+
+False
+
+
+False
+
+
+
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+False
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+677,457;677,436;452,436;452,408;453,408;453,400
+rzRRpqBkm0yfwy3aI3cqxwAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+2T5uPBt7eke2HwgRYpnCMAAA
+
+False
+1.5707963267949
+15
+rzRRpqBkm0yfwy3aI3cqxwAA
+
+
+False
+1.5707963267949
+30
+rzRRpqBkm0yfwy3aI3cqxwAA
+
+
+False
+-1.5707963267949
+15
+rzRRpqBkm0yfwy3aI3cqxwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+KFvQin5iLEGAVIH9T8e6rAAA
+
+
+False
+0.523598775598299
+30
+epTail
+r9ZKI6MesUucCgcfzS0QfgAA
+
+
+False
+0.523598775598299
+25
+epHead
+KFvQin5iLEGAVIH9T8e6rAAA
+
+
+-0.88847960161191
+20.6155281280883
+epTail
+0..1
+r9ZKI6MesUucCgcfzS0QfgAA
+
+
+False
+-0.785398163397448
+40
+epHead
+KFvQin5iLEGAVIH9T8e6rAAA
+
+
+False
+0.785398163397448
+40
+epTail
+r9ZKI6MesUucCgcfzS0QfgAA
+
+
+False
+-1016
+-1000
+50
+8
+KFvQin5iLEGAVIH9T8e6rAAA
+
+
+False
+-1016
+-1000
+50
+8
+r9ZKI6MesUucCgcfzS0QfgAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+781,457;781,436;452,436;452,408;453,408;453,400
+BM7xfj//AUeshsMNOxgsxgAA
+BXtJ8bydRkaG4zZDEHjyvAAA
+m1sFZHb29ECv9kAxRQcW5gAA
+
+False
+1.5707963267949
+15
+BM7xfj//AUeshsMNOxgsxgAA
+
+
+False
+1.5707963267949
+30
+BM7xfj//AUeshsMNOxgsxgAA
+
+
+False
+-1.5707963267949
+15
+BM7xfj//AUeshsMNOxgsxgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+bk8NyfMQ3UuXujm5JaC0lAAA
+
+
+False
+0.523598775598299
+30
+epTail
++gLQ5RBZP0y5F8LsLF0a7gAA
+
+
+False
+0.523598775598299
+25
+epHead
+bk8NyfMQ3UuXujm5JaC0lAAA
+
+
+-0.817644881492434
+21.9317121994613
+epTail
+0..1
++gLQ5RBZP0y5F8LsLF0a7gAA
+
+
+False
+-0.785398163397448
+40
+epHead
+bk8NyfMQ3UuXujm5JaC0lAAA
+
+
+False
+0.785398163397448
+40
+epTail
++gLQ5RBZP0y5F8LsLF0a7gAA
+
+
+False
+-1016
+-1000
+50
+8
+bk8NyfMQ3UuXujm5JaC0lAAA
+
+
+False
+-1016
+-1000
+50
+8
++gLQ5RBZP0y5F8LsLF0a7gAA
+
+
+
+
+16
+
+common
+nunAvzsMpEeElylKkdpPBgAA
+2
+/8Anp5uSOUG7NmHhFk/nrAAA
+2S195WIy+0Syn1xEV2jn8AAA
+
+
+phase
+nunAvzsMpEeElylKkdpPBgAA
+4
+N8ckb8OYP0SfE9Y3pFPHeQAA
+pGbr5OSan0KaHW/kfKG06gAA
+q4nmbqnRj02UOcrLD1YKXgAA
+mwWMDNy96U2S95ynkMKM6gAA
+2
+mWEP+8jbjE24hKhlVCG8uQAA
+YjWzlZsOqEqUJsdVQD/XAgAA
+1
+
+name
+1
+A9TZ2/XE7UqgiiSvVEDLQwAA
+
+
+
+implml file
+nunAvzsMpEeElylKkdpPBgAA
+4
+t73r2IX7MECggYesswXDJAAA
+PI856VbJ1EmqFDdtNo2osAAA
+QufBQRkAJEWVH35TPaGEcgAA
+OBSt/hkfT0uBJX9vhn/ZYAAA
+2
+SGqBWylq6kqsO+xgQtMRGQAA
+3frzsw0XSEq7O8j/X125ewAA
+
+
+tag
+nunAvzsMpEeElylKkdpPBgAA
+4
+fFUPdkT+cECZRPlQsVRNmgAA
+hhUPNV2dYUe93B+roOUBxAAA
+IqDATwgrQU+YDY6SgU4zPAAA
+C6uIjH9Jz06qP1N9c9sHRgAA
+1
+Q4SS4jSQ20i54ioZw+85jQAA
+2
+
+name
+1
+DEez7Bc9Uk2h44eLm4tOTAAA
+
+
+value
+1
+DEez7Bc9Uk2h44eLm4tOTAAA
+
+
+
+tempfeature
+nunAvzsMpEeElylKkdpPBgAA
+4
+q4XlSDOPYU+NPe527blyDAAA
+OPmimASZgkeXIjYxldjyCwAA
+99Yd5gndkkyskqSs6f7DxgAA
+5Z63Ifg2AkSGODIoh2d+pQAA
+2
+MU/1J6u8VEukQZBFAc2A2QAA
+ePQ/2OtUrky7xn80sS850gAA
+3
+
+ref
+1
+hEercfKAykep6GRNpygwAAAA
+
+
+type
+1
+hEercfKAykep6GRNpygwAAAA
+
+
+value
+0..1
+hEercfKAykep6GRNpygwAAAA
+
+
+
+tempseqfeature
+nunAvzsMpEeElylKkdpPBgAA
+4
+EQYzSHCrWUaPx/wRaFPzOwAA
+WUJqg6xiME6JRZYBE52z6QAA
+81QcggEHtESSYNzW/5PV2QAA
+VmcXcfWsuU+bWPIkjuPHUgAA
+2
+xx3gzV5BjUSwJg5lsak/CgAA
+uIda2Q00s0uCEjYvkFMChwAA
+1
+
+ref
+1
+MuE9xXdvYEODEr1y4vsX9QAA
+
+
+
+nunAvzsMpEeElylKkdpPBgAA
+4
+lDijJz+lnkadB0oxsMOAAQAA
+JjVQpSvmgEm54HeP9POXvwAA
+eoVARvn3OEqynyhClbO8yAAA
+0dBBCuYIWkq/zCoyhQ140wAA
+2
+
+0..*
+ACScvSJbSEqRvLIQ0IWV9AAA
+hEercfKAykep6GRNpygwAAAA
+4
+TEn2uTNL9ESnQTpl5oyOKgAA
+TCdbptC6Hkey6HYbSHSlUwAA
+fV+2hhuvbE+GX25nb51XBwAA
+KAXmkwuIp0aDj+4oQ50XfgAA
+
+
+akAggregate
+ACScvSJbSEqRvLIQ0IWV9AAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+nXLYOXclLEq/2y6E25OcVAAA
+mJZcS8A23UCjjPXR4Js0fgAA
+Rx5zN26i2k2Fvy+F7kNHTwAA
+uI7s6qqcGEqx84dV+JAmqwAA
+
+
+
+nunAvzsMpEeElylKkdpPBgAA
+4
+f+FpiX4HAUiGKFcnimx97AAA
+yIipsqN2aUahEVrhm8LOiwAA
+JZ+fwjd92keC3R4jIuX9owAA
+FzSHhWKaTke2a/z/KlTxcAAA
+2
+
+0..*
+DefM64TTyU2ZcEZyZ7rTnQAA
+MuE9xXdvYEODEr1y4vsX9QAA
+4
+DeST4IpeUkuKir0N1A+aMQAA
+qcnw+p3bqEiOv/Nwq7EgoQAA
+HTxhSxf5J0WgxsqCKpBMAAAA
+/LWDzwsu0EawQTr1UGbTVgAA
+
+
+akAggregate
+DefM64TTyU2ZcEZyZ7rTnQAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+GYmmwpC+cE+fi1tnRZpY9gAA
+Dsz6KvcRzUGpkTDhjlSRSQAA
+4Xv4IN4btESYQH5UO7Z1cgAA
+08SxPJBOcEqe/OQitUB50AAA
+
+
+
+nunAvzsMpEeElylKkdpPBgAA
+4
+qDs4zMrgQUu/VKS9qmKz4wAA
++fo9wKErd0qKhHlrtKowVQAA
+c9CYUcVs5ESBJb/0NuVAHgAA
+5MSI9Omy3EKF/ZGqLtDJIAAA
+2
+
+0..*
+XoJDBeddjkqF9PVLMr+HVgAA
+hEercfKAykep6GRNpygwAAAA
+4
+8syy+G5BVkCkzztWIIof1gAA
+qjSUWtPas0G4tIeu/8AH7AAA
+ClDwYsQriEati/Nbvlx8OQAA
+6QdZ3MQgCkSArLSSrf+kWQAA
+
+
+akAggregate
+XoJDBeddjkqF9PVLMr+HVgAA
+MuE9xXdvYEODEr1y4vsX9QAA
+4
+naNIibz2akyw2UwxuvDGZgAA
+8JbJbpjl0k+TZK+PrtHQxgAA
+F9vzq6GvgEmLf4KzlJ/wugAA
+6a9Hd+IgAEWymmjI9AlFPgAA
+
+
+
+container
+nunAvzsMpEeElylKkdpPBgAA
+4
+BXtJ8bydRkaG4zZDEHjyvAAA
+ZrMXdpPY1Ues7G33I2U5/QAA
+hkIt753UDkOqOpsvMF1yugAA
+JYbuLcvZYUuBlwhbmGv9egAA
+1
+taqNNc4Me0uannQ7Vlc89gAA
+8
+ABzc1o7mCkiMBst076lYvAAA
+aULbbut4DECnPwmgTtTx2gAA
+5lW8exzmFUirT6PzXp05/AAA
+eXkeLjSvuU6MRxUlhWndcAAA
+A/HqW/8oKkubU3VPXj3eWQAA
+MhZygEis/U2M0wvtfV4YYQAA
+KFvQin5iLEGAVIH9T8e6rAAA
+bk8NyfMQ3UuXujm5JaC0lAAA
+2
+
+condition
+QHug9JDMF0eIdhAMRc3BlwAA
+
+
+value
+QHug9JDMF0eIdhAMRc3BlwAA
+
+
+
+nunAvzsMpEeElylKkdpPBgAA
+4
+XbKd2ozKm0KjBH2+B7EbFQAA
+cx5HEnUDjkKIcEHbXnmY6QAA
+Xx8upWKNs0SUSG7RBq4LEQAA
+sNaKIINw7UyrvzWXhDmn8wAA
+2
+
+1
+fOjqr0wnzEqQV2QbncXRyAAA
+zjzhCfIGK0Ooz0gx49BvDwAA
+4
+qt2dV6wVZk2xQ8O7aZwO1QAA
+/z7KGc76rEaqbSPpLyDtQQAA
+uiOZ0KB9r0GHM82RdkSvGwAA
+FFP7IHWkN0aJxFT/1EqaigAA
+
+
+1
+fOjqr0wnzEqQV2QbncXRyAAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+1MMX4GDxXUi7GjKlTVKNVgAA
+RA9vB3//80CoXo0NzBR6rAAA
+nT3LpEfP30ybhNGs+O27TAAA
+ktsmWvzHm0u2QeBz00go2gAA
+
+
+
+nunAvzsMpEeElylKkdpPBgAA
+QHug9JDMF0eIdhAMRc3BlwAA
+IONricIIR0WGo59WsXpFtgAA
+4
+m7xPi5BLfkm9e2kcVPCUxAAA
+OEWOhp7dtk26r3VphiSNrwAA
+dTW+1qCx9E2PbuJZwc7G7gAA
+0ykP3jgL9kCPtJ/1aOYqQwAA
+
+
+nunAvzsMpEeElylKkdpPBgAA
+4
+JGJJrvFGokuwAuL+iejuGQAA
+wQDxUEaM1k2xJjjWkLsMcwAA
+/xn+temNuE+205GV2L0f2gAA
+xF1jr6X3O0K6c2SVgDv+ywAA
+2
+
+zYO7Oxc95E6KdcR2XpasaAAA
+IONricIIR0WGo59WsXpFtgAA
+4
+qnHkuoKx106+BYE+LUQtDwAA
+FFk2PvxCdUSAWeqc4WyumQAA
+vE8jpuRvkka3P0mYLJF8iwAA
+bwrWtyvnCEOwkIRJvFxmHAAA
+
+
+akAggregate
+0..*
+zYO7Oxc95E6KdcR2XpasaAAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+A7inrXPBM0OXakiq/FvO/wAA
+731HeOV/+Em/AUMRahjHzAAA
+KrL9XCcPtUS7ABk0PptIugAA
+9bw+bjGuTk2UhVE7s6v5ogAA
+
+
+
+outputSubDir
+nunAvzsMpEeElylKkdpPBgAA
+8
+2T5uPBt7eke2HwgRYpnCMAAA
+//nXFFeA0EKGX1Zc18aCzwAA
+S2mAQKq9Y0yCSbV56srKxwAA
+9UFPdyghe0mo1UxopenN6wAA
+m1sFZHb29ECv9kAxRQcW5gAA
+wRqhwTujYki/Lp4EyXVtRQAA
+AsHbUNhps0OQ9BfREA4eNAAA
+Gj/HOJSfP0is9coJtP6lXwAA
+2
+r9ZKI6MesUucCgcfzS0QfgAA
++gLQ5RBZP0y5F8LsLF0a7gAA
+1
+
+value
+NuUKs/mthU6Lxh76zy/UYwAA
+
+
+
+nunAvzsMpEeElylKkdpPBgAA
+4
+FqEmtfhZP0yvsRDUVGRNxgAA
+AVpaj5e93UGbI3rCX4aPHQAA
+1UwmvOI8HUKCxNtlxHaCawAA
+CSNDh0Zbo0+b8vLXvrfW+wAA
+2
+
+0..1
+rzRRpqBkm0yfwy3aI3cqxwAA
+NuUKs/mthU6Lxh76zy/UYwAA
+4
+cQglapci3kmBoYtTQy73RQAA
+2VwG90y+X0CLJoic/n6tFgAA
+WEIx6/fcNU6IgI+i70cmQgAA
+PU0/W99Y9kqy1/6HlGH0pwAA
+
+
+akAggregate
+rzRRpqBkm0yfwy3aI3cqxwAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+r6eRUvMhvUmpyOw9Pz6N1QAA
+DR82HdfhIUWzLgMfaRac3wAA
+SiywKdY/aEqjgK18qKv7kAAA
+a8VZOZ5dak+Y8SONKr6evwAA
+
+
+
+nunAvzsMpEeElylKkdpPBgAA
+4
+dUrSwDKAKEu3+zLxMPZaIwAA
+ERGMmShXbU2+7HxuYHBk8gAA
+ikxxeX8f2kiAUOdxwrywOwAA
+gvSAjIPYrECqd4sajy2j+wAA
+2
+
+0..1
+BM7xfj//AUeshsMNOxgsxgAA
+NuUKs/mthU6Lxh76zy/UYwAA
+4
+IWyM8Abdp0aFdUyH2LeR+AAA
+wnXqAc2wAEG9IrfIdZskuAAA
+QMt1zHcMLEOZFl1bcJ3FRAAA
+uGaNmZ6d6kmSpCLGOymxAQAA
+
+
+akAggregate
+BM7xfj//AUeshsMNOxgsxgAA
+QHug9JDMF0eIdhAMRc3BlwAA
+4
+xrwQNzvkYEOLRTC/V2czAQAA
+7FAPDNEAe0SiTC9kHSm+BgAA
+xwDzPSmjDEekIiVkDoYaGgAA
+HfV42i/6Tki3op6A+jQ67QAA
+
+
+
+
+imageml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+imageml
+I0mGM2cIbES/2vP45srj7AAA
+
+Oz6AUWlj3Ei96BpX7wdxtAAA
+
+
+
+
+makeml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+makeml
+2C+Cmz3pQU69bnFdQ4NEQwAA
+
+gkjy8NS9rki3NBrJjDqeIQAA
+
+
+
+
+gcfml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+gcfml
+V+1ArsAv8UiFK7JhBEzPggAA
+
+XFblftP7akSDLFNty78ILgAA
+11
+
+clMaroon
+$00B9FFFF
+92
+20
+86
+59
+False
+0NN2NTb+K0GnRvsVagJUAAAA
+
+
+1
+file
+
+
+False
+
+
+False
+
+
+
+0NN2NTb+K0GnRvsVagJUAAAA
+
+
+False
+0NN2NTb+K0GnRvsVagJUAAAA
+
+
+False
+0NN2NTb+K0GnRvsVagJUAAAA
+
+
+
+clMaroon
+$00B9FFFF
+28
+144
+80
+46
+False
+8xSNygiE4km9qtTz0lwzMQAA
+
+
+1
+setting
+
+
+False
+
+
+False
+
+
+
+8xSNygiE4km9qtTz0lwzMQAA
+
+
+False
+8xSNygiE4km9qtTz0lwzMQAA
+
+
+False
+8xSNygiE4km9qtTz0lwzMQAA
+
+
+
+clMaroon
+$00B9FFFF
+80,144;118,78
+CLkcptWRtUmcTy6uhI1XygAA
+Jdyoma73zU6scrgVlhqoFwAA
+RcAFldfCDUiCe4pE6ajUiAAA
+
+False
+1.5707963267949
+15
+CLkcptWRtUmcTy6uhI1XygAA
+
+
+False
+1.5707963267949
+30
+CLkcptWRtUmcTy6uhI1XygAA
+
+
+False
+-1.5707963267949
+15
+CLkcptWRtUmcTy6uhI1XygAA
+
+
+False
+-0.523598775598299
+30
+epHead
+x8TqIv4G1k+wirLi5+frGAAA
+
+
+False
+0.523598775598299
+30
+epTail
+xbbHGPUK5E2jvUJ05zW1gwAA
+
+
+False
+0.523598775598299
+25
+epHead
+x8TqIv4G1k+wirLi5+frGAAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+xbbHGPUK5E2jvUJ05zW1gwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+x8TqIv4G1k+wirLi5+frGAAA
+
+
+False
+0.785398163397448
+40
+epTail
+xbbHGPUK5E2jvUJ05zW1gwAA
+
+
+False
+-1148
+-996
+50
+8
+x8TqIv4G1k+wirLi5+frGAAA
+
+
+False
+-1148
+-996
+50
+8
+xbbHGPUK5E2jvUJ05zW1gwAA
+
+
+
+clMaroon
+$00B9FFFF
+180
+144
+89
+46
+False
+Y0FG+nLPIkCUVfqHSn052gAA
+
+
+1
+xsl:stylesheet
+
+
+False
+
+
+False
+
+
+
+Y0FG+nLPIkCUVfqHSn052gAA
+
+
+False
+Y0FG+nLPIkCUVfqHSn052gAA
+
+
+False
+Y0FG+nLPIkCUVfqHSn052gAA
+
+
+
+clMaroon
+$00B9FFFF
+207,144;156,78
+Edpn1GnNrkK8TAcwlSjFRwAA
+Jdyoma73zU6scrgVlhqoFwAA
+4BYArj9b10+WEoIpPr+QCwAA
+
+False
+1.5707963267949
+15
+Edpn1GnNrkK8TAcwlSjFRwAA
+
+
+False
+1.5707963267949
+30
+Edpn1GnNrkK8TAcwlSjFRwAA
+
+
+False
+-1.5707963267949
+15
+Edpn1GnNrkK8TAcwlSjFRwAA
+
+
+False
+-0.523598775598299
+30
+epHead
+m9gWVhQ/zUyuRhIvfKSq8AAA
+
+
+False
+0.523598775598299
+30
+epTail
+Q/8ql+Vuzkec7bwh1EEGFQAA
+
+
+False
+0.523598775598299
+25
+epHead
+m9gWVhQ/zUyuRhIvfKSq8AAA
+
+
+-0.523598775598299
+25
+epTail
+1
+Q/8ql+Vuzkec7bwh1EEGFQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+m9gWVhQ/zUyuRhIvfKSq8AAA
+
+
+False
+0.785398163397448
+40
+epTail
+Q/8ql+Vuzkec7bwh1EEGFQAA
+
+
+False
+-1148
+-996
+50
+8
+m9gWVhQ/zUyuRhIvfKSq8AAA
+
+
+False
+-1148
+-996
+50
+8
+Q/8ql+Vuzkec7bwh1EEGFQAA
+
+
+
+clMaroon
+$00B9FFFF
+112
+232
+101
+59
+False
+1AcPCR57Q0a21p8zgmownwAA
+
+
+1
+xsl:output
+
+
+False
+
+
+False
+
+
+
+1AcPCR57Q0a21p8zgmownwAA
+
+
+False
+1AcPCR57Q0a21p8zgmownwAA
+
+
+False
+1AcPCR57Q0a21p8zgmownwAA
+
+
+
+clMaroon
+$00B9FFFF
+181,232;209,189
+jKymlkqbbEGJL8hTuA4lowAA
+4BYArj9b10+WEoIpPr+QCwAA
+ft2YpT4rYkqiOFoZvMisrgAA
+
+False
+1.5707963267949
+15
+jKymlkqbbEGJL8hTuA4lowAA
+
+
+False
+1.5707963267949
+30
+jKymlkqbbEGJL8hTuA4lowAA
+
+
+False
+-1.5707963267949
+15
+jKymlkqbbEGJL8hTuA4lowAA
+
+
+False
+-0.523598775598299
+30
+epHead
+zZi5WaO5XE2jkNFbiTMzTAAA
+
+
+False
+0.523598775598299
+30
+epTail
+U6OM61MtzkKCnIJtqrGUgQAA
+
+
+False
+0.523598775598299
+25
+epHead
+zZi5WaO5XE2jkNFbiTMzTAAA
+
+
+-0.523598775598299
+25
+epTail
+1
+U6OM61MtzkKCnIJtqrGUgQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+zZi5WaO5XE2jkNFbiTMzTAAA
+
+
+False
+0.785398163397448
+40
+epTail
+U6OM61MtzkKCnIJtqrGUgQAA
+
+
+False
+-1148
+-996
+50
+8
+zZi5WaO5XE2jkNFbiTMzTAAA
+
+
+False
+-1148
+-996
+50
+8
+U6OM61MtzkKCnIJtqrGUgQAA
+
+
+
+clMaroon
+$00B9FFFF
+232
+244
+90
+46
+False
+pGXKqhizL0+bptHyaeJW+gAA
+
+
+1
+xsl:template
+
+
+False
+
+
+False
+
+
+
+pGXKqhizL0+bptHyaeJW+gAA
+
+
+False
+pGXKqhizL0+bptHyaeJW+gAA
+
+
+False
+pGXKqhizL0+bptHyaeJW+gAA
+
+
+
+clMaroon
+$00B9FFFF
+265,244;236,189
+80y69KlvtkyLI9fXZ63EPQAA
+4BYArj9b10+WEoIpPr+QCwAA
+3AWO9V+LQ0uyIPA+rve3lAAA
+
+False
+1.5707963267949
+15
+80y69KlvtkyLI9fXZ63EPQAA
+
+
+False
+1.5707963267949
+30
+80y69KlvtkyLI9fXZ63EPQAA
+
+
+False
+-1.5707963267949
+15
+80y69KlvtkyLI9fXZ63EPQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+mFf1jezitEysnpnhm+kZCwAA
+
+
+False
+0.523598775598299
+30
+epTail
+ZWy+omRz4EOKB/GHl1/T9AAA
+
+
+False
+0.523598775598299
+25
+epHead
+mFf1jezitEysnpnhm+kZCwAA
+
+
+-0.523598775598299
+25
+epTail
+1
+ZWy+omRz4EOKB/GHl1/T9AAA
+
+
+False
+-0.785398163397448
+40
+epHead
+mFf1jezitEysnpnhm+kZCwAA
+
+
+False
+0.785398163397448
+40
+epTail
+ZWy+omRz4EOKB/GHl1/T9AAA
+
+
+False
+-1148
+-996
+50
+8
+mFf1jezitEysnpnhm+kZCwAA
+
+
+False
+-1148
+-996
+50
+8
+ZWy+omRz4EOKB/GHl1/T9AAA
+
+
+
+clMaroon
+$00B9FFFF
+232
+344
+86
+43
+yPed4fBEF0et5jplS0KL1QAA
+
+
+1
+xsl:
+
+
+False
+
+
+False
+
+
+
+False
+yPed4fBEF0et5jplS0KL1QAA
+
+
+False
+yPed4fBEF0et5jplS0KL1QAA
+
+
+False
+yPed4fBEF0et5jplS0KL1QAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+275,344;275,289
+Y+SiYbvoK0qRL5azXByV0gAA
+3AWO9V+LQ0uyIPA+rve3lAAA
+4curCB5tE0y4dYaDqwzFqQAA
+
+False
+1.5707963267949
+15
+Y+SiYbvoK0qRL5azXByV0gAA
+
+
+False
+1.5707963267949
+30
+Y+SiYbvoK0qRL5azXByV0gAA
+
+
+False
+-1.5707963267949
+15
+Y+SiYbvoK0qRL5azXByV0gAA
+
+
+False
+-0.523598775598299
+30
+epHead
+GJXnVHy3pUuzUgUCkzK6FgAA
+
+
+False
+0.523598775598299
+30
+epTail
+cwjGmzSusEOq9Gj4PZo9mwAA
+
+
+False
+0.523598775598299
+25
+epHead
+GJXnVHy3pUuzUgUCkzK6FgAA
+
+
+-0.523598775598299
+25
+epTail
+1..*
+cwjGmzSusEOq9Gj4PZo9mwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+GJXnVHy3pUuzUgUCkzK6FgAA
+
+
+False
+0.785398163397448
+40
+epTail
+cwjGmzSusEOq9Gj4PZo9mwAA
+
+
+False
+-1148
+-996
+50
+8
+GJXnVHy3pUuzUgUCkzK6FgAA
+
+
+False
+-1148
+-996
+50
+8
+cwjGmzSusEOq9Gj4PZo9mwAA
+
+
+
+
+11
+
+file
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+Jdyoma73zU6scrgVlhqoFwAA
+b6Qe6bA46UCV3nJ6buDPhwAA
+zywqqoD9KUyEg7H1xCO/XgAA
+WW2Oq7CWfEC7nZwvSrGpYgAA
+2
+x8TqIv4G1k+wirLi5+frGAAA
+m9gWVhQ/zUyuRhIvfKSq8AAA
+2
+
+name
+0NN2NTb+K0GnRvsVagJUAAAA
+
+
+target
+0NN2NTb+K0GnRvsVagJUAAAA
+
+
+
+setting
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+RcAFldfCDUiCe4pE6ajUiAAA
+h2CquA3TzEi6huNrhEto7QAA
+ncPt0SADRkiyNy3x1MFSRAAA
+TLbO8Rj1AEat/yI9Eu3yjgAA
+1
+xbbHGPUK5E2jvUJ05zW1gwAA
+1
+
+ref
+1
+8xSNygiE4km9qtTz0lwzMQAA
+
+
+
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+FvMvaBDG0UGqMF8O0M3szQAA
+ufaBujZD9Em/8baqgZCmpAAA
+EGfsWfiCEU6Kf/4EaZtfpQAA
+VrnRFooWxE6SvdGe3R4CxAAA
+2
+
+0..*
+CLkcptWRtUmcTy6uhI1XygAA
+8xSNygiE4km9qtTz0lwzMQAA
+4
+u5KYBJ0gD0mwyu8B9qP6bAAA
+cOhivJSweEOQUozlVDTR3QAA
+W5Vgx5cQoUqXCmc1cWrOZgAA
+SLd8338SpEeH7wpOgebnvgAA
+
+
+akAggregate
+CLkcptWRtUmcTy6uhI1XygAA
+0NN2NTb+K0GnRvsVagJUAAAA
+4
+vhbevDI3jkqKPA+GLeGoOgAA
+OCEro0FXQU2mFCcx0eAHrwAA
+A9YIucGQk0aTrybcJhiIbwAA
+sN5mmeLV60KRB1chJ0ZqcgAA
+
+
+
+xsl:stylesheet
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+4BYArj9b10+WEoIpPr+QCwAA
+dCit6j/vR0Krc5CnE38DLAAA
+/wq5okCFTE+YVXlM9TMd3AAA
+aD9dNbbDTUWqtpugEURuNgAA
+3
+Q/8ql+Vuzkec7bwh1EEGFQAA
+zZi5WaO5XE2jkNFbiTMzTAAA
+mFf1jezitEysnpnhm+kZCwAA
+1
+
+version
+Y0FG+nLPIkCUVfqHSn052gAA
+
+
+
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+W7h/8eYPskmnwomltgs98AAA
+QnpEzK9mVUSyXAu+rxr4VwAA
+lPEPipNPHUqNzkEg7U2N2gAA
+lhJzUNN3C0+dr2obkO72RQAA
+2
+
+1
+Edpn1GnNrkK8TAcwlSjFRwAA
+Y0FG+nLPIkCUVfqHSn052gAA
+4
+47F9iqUijkKxZwLDyvywZQAA
+zfzIwdDzbki3Tf8/MJiREgAA
+sw1pGy546kSg4kezTSnDaAAA
+prP90vWjYUWS06apPPLX0AAA
+
+
+akAggregate
+Edpn1GnNrkK8TAcwlSjFRwAA
+0NN2NTb+K0GnRvsVagJUAAAA
+4
+LM5L2yTlXkWSxJg3iFAAbwAA
+vbLwqjPV+kq0fwJr+tbpGwAA
+EOeSibSBf0WapJWU8t3sCgAA
+g98LHacOvU6gamPh5UU3TwAA
+
+
+
+xsl:output
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+ft2YpT4rYkqiOFoZvMisrgAA
+ig+6oMwYzEa0sewqxnM2lwAA
+ZofOTGjMyUW6UFCCH3w9YwAA
+16a/3Jl3yUKorvnQOzlduwAA
+1
+U6OM61MtzkKCnIJtqrGUgQAA
+2
+
+method
+1AcPCR57Q0a21p8zgmownwAA
+
+
+encoding
+1AcPCR57Q0a21p8zgmownwAA
+
+
+
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+XoMRU3io90G36TQ/U0CVVwAA
+M7v50slC+0yKCFbErqHHfgAA
+aqXS1Q15d0W7qUC497mnZwAA
+8Cqn7TeIOUGHRx9OlGK/zwAA
+2
+
+1
+jKymlkqbbEGJL8hTuA4lowAA
+1AcPCR57Q0a21p8zgmownwAA
+4
+JYrQNO6xyUaq5AIdWe4g+gAA
+SrzRH47iSU6J7I70jTI/ngAA
+xPGxjgkc40ikQRYkdn1SlQAA
+WqIHpYMXPUuHcWvd3OKk9AAA
+
+
+akAggregate
+jKymlkqbbEGJL8hTuA4lowAA
+Y0FG+nLPIkCUVfqHSn052gAA
+4
+QGh16Fu90k2L0fMRj3oIngAA
+8KhvkOdcXkSMPeOjWJL/MQAA
+lCbO3RXsLEOBxCxuoJV+RQAA
+90vaJtlEYka3EdcDBkSnxQAA
+
+
+
+xsl:template
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+3AWO9V+LQ0uyIPA+rve3lAAA
+WF4wgh1w0Uiw0m1hYwJSVAAA
+ielEBWtNFE6tQN/HC7Qz0AAA
+gqYeILj6cU+Bp1kKF9JMIwAA
+2
+ZWy+omRz4EOKB/GHl1/T9AAA
+GJXnVHy3pUuzUgUCkzK6FgAA
+1
+
+match
+pGXKqhizL0+bptHyaeJW+gAA
+
+
+
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+ZyG1KYn3e0mPcJe3vctoSwAA
+0WRL5v4YE028/n8q7Mh9xQAA
+d0490/5xIkSluRKRdEDkQwAA
+St4S9Vu4YkOfMllIJfQ/nAAA
+2
+
+1
+80y69KlvtkyLI9fXZ63EPQAA
+pGXKqhizL0+bptHyaeJW+gAA
+4
+/lBKB9C2jkS36WrjV2lwOAAA
+ayHsdPbbMUCV+JR8AkXGYgAA
+eht5DkO+x0OD+fY7PqxtBgAA
+EvpeXFaDRk2yRfxzIa5xOQAA
+
+
+akAggregate
+80y69KlvtkyLI9fXZ63EPQAA
+Y0FG+nLPIkCUVfqHSn052gAA
+4
+xnSs++0eiE+a2PGdWk34ywAA
+QuGA5NzSpke7sEK1QM0vNQAA
+MGWpYuYFiEm85u2OHMMFJQAA
+1XuthdvMw0qjPjImIxnbswAA
+
+
+
+xsl:
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+4curCB5tE0y4dYaDqwzFqQAA
+1GAzUCeYLUKgxkdKoQ+GWAAA
+6tTc1fBS3EqovAPepXIllwAA
+OdW6NHCNy0y9YEmyJgQjUgAA
+1
+cwjGmzSusEOq9Gj4PZo9mwAA
+
+
+V+1ArsAv8UiFK7JhBEzPggAA
+4
+/N+UY3fRtkaxXsgXw6oEFgAA
+WoSQHOaHyUqa92WrXMGZ8AAA
+JS6F5/ZXRku6yKyW4EdIVwAA
+FFeyvlkJn0+FpgzP5+zvdQAA
+2
+
+1..*
+Y+SiYbvoK0qRL5azXByV0gAA
+yPed4fBEF0et5jplS0KL1QAA
+4
+kMlEYKfM+EWLa1RfrOo4fwAA
+/3FOgLVzXEGGoRG5wTF/IAAA
+xxvh5xNXX0mwPq3c4YVUcQAA
+RhfmBS/kykCeD+Ht8ZaecwAA
+
+
+akAggregate
+Y+SiYbvoK0qRL5azXByV0gAA
+pGXKqhizL0+bptHyaeJW+gAA
+4
+ZMLtp2NqEkW8wlof8D9tRQAA
+AChd79+4RkWhwmiHbEdg8QAA
+Uz7/dV2+gEKcdrIxcZRC3wAA
+5czjoEZUc0KbwespIPag+wAA
+
+
+
+
+convertprojectml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+convertprojectml
+dJLeoE8dBU6wuilHUj+y3gAA
+
+zwJUtzHaJU21M83o154H7wAA
+12
+
+clMaroon
+$00B9FFFF
+112
+8
+109
+43
+False
+pY4k1EkTmk6ZYPgvdrAXtgAA
+
+
+1
+convertprojectml
+
+
+False
+
+
+False
+
+
+
+pY4k1EkTmk6ZYPgvdrAXtgAA
+
+
+False
+pY4k1EkTmk6ZYPgvdrAXtgAA
+
+
+False
+pY4k1EkTmk6ZYPgvdrAXtgAA
+
+
+
+clMaroon
+$00B9FFFF
+20
+124
+87
+59
+False
+Bd5einjYSUuwBOyRucxDOgAA
+
+
+1
+targetProject
+
+
+False
+
+
+False
+
+
+
+Bd5einjYSUuwBOyRucxDOgAA
+
+
+False
+Bd5einjYSUuwBOyRucxDOgAA
+
+
+False
+Bd5einjYSUuwBOyRucxDOgAA
+
+
+
+clMaroon
+$00B9FFFF
+87,124;149,50
+False
+A6cb4Q7lhEuoG/7OMN+p9wAA
+iv3WNEaVUkyVZFthO5NWpAAA
+VpqNyMzcgUKFjkrP2MYKXAAA
+
+False
+1.5707963267949
+15
+A6cb4Q7lhEuoG/7OMN+p9wAA
+
+
+False
+1.5707963267949
+30
+A6cb4Q7lhEuoG/7OMN+p9wAA
+
+
+False
+-1.5707963267949
+15
+A6cb4Q7lhEuoG/7OMN+p9wAA
+
+
+False
+-0.523598775598299
+30
+epHead
+4qk8cKW65kie31vCKuC5LQAA
+
+
+False
+0.523598775598299
+30
+epTail
+2+NhaybpyE+grJZ6zRo07AAA
+
+
+False
+0.523598775598299
+25
+epHead
+4qk8cKW65kie31vCKuC5LQAA
+
+
+-0.523598775598299
+25
+epTail
+1
+2+NhaybpyE+grJZ6zRo07AAA
+
+
+False
+-0.785398163397448
+40
+epHead
+4qk8cKW65kie31vCKuC5LQAA
+
+
+False
+0.785398163397448
+40
+epTail
+2+NhaybpyE+grJZ6zRo07AAA
+
+
+False
+-1164
+-1160
+50
+8
+4qk8cKW65kie31vCKuC5LQAA
+
+
+False
+-1164
+-1160
+50
+8
+2+NhaybpyE+grJZ6zRo07AAA
+
+
+
+clMaroon
+$00B9FFFF
+192
+124
+91
+46
+False
+8tRKm9V57EqPhwTgLVrWPgAA
+
+
+1
+layer
+
+
+False
+
+
+False
+
+
+
+8tRKm9V57EqPhwTgLVrWPgAA
+
+
+False
+8tRKm9V57EqPhwTgLVrWPgAA
+
+
+False
+8tRKm9V57EqPhwTgLVrWPgAA
+
+
+
+clMaroon
+$00B9FFFF
+224,124;179,50
+False
+SSk55GHANUS/X4vl9shC8QAA
+iv3WNEaVUkyVZFthO5NWpAAA
+g+ZdW0H0HESi/Ogvi7viDwAA
+
+False
+1.5707963267949
+15
+SSk55GHANUS/X4vl9shC8QAA
+
+
+False
+1.5707963267949
+30
+SSk55GHANUS/X4vl9shC8QAA
+
+
+False
+-1.5707963267949
+15
+SSk55GHANUS/X4vl9shC8QAA
+
+
+False
+-0.523598775598299
+30
+epHead
+v71Cv0dawUKL+j5BmN9CRAAA
+
+
+False
+0.523598775598299
+30
+epTail
+e3mjKSqfHkG5KNzBPWb2xgAA
+
+
+False
+0.523598775598299
+25
+epHead
+v71Cv0dawUKL+j5BmN9CRAAA
+
+
+-0.523598775598299
+25
+epTail
+1..*
+e3mjKSqfHkG5KNzBPWb2xgAA
+
+
+False
+-0.785398163397448
+40
+epHead
+v71Cv0dawUKL+j5BmN9CRAAA
+
+
+False
+0.785398163397448
+40
+epTail
+e3mjKSqfHkG5KNzBPWb2xgAA
+
+
+False
+-1164
+-1160
+50
+8
+v71Cv0dawUKL+j5BmN9CRAAA
+
+
+False
+-1164
+-1160
+50
+8
+e3mjKSqfHkG5KNzBPWb2xgAA
+
+
+
+clMaroon
+$00B9FFFF
+196
+220
+86
+56
+False
+NcePGMdhZE+ri6hKbPWURgAA
+
+
+1
+folder
+
+
+False
+
+
+False
+
+
+
+NcePGMdhZE+ri6hKbPWURgAA
+
+
+False
+NcePGMdhZE+ri6hKbPWURgAA
+
+
+False
+NcePGMdhZE+ri6hKbPWURgAA
+
+
+
+clMaroon
+$00B9FFFF
+238,220;237,169
+False
+GlHcJZ4KsUGJaYdLveiVFQAA
+g+ZdW0H0HESi/Ogvi7viDwAA
+PTTthVdFJkSuxFmOBKW8BQAA
+
+False
+1.5707963267949
+15
+GlHcJZ4KsUGJaYdLveiVFQAA
+
+
+False
+1.5707963267949
+30
+GlHcJZ4KsUGJaYdLveiVFQAA
+
+
+False
+-1.5707963267949
+15
+GlHcJZ4KsUGJaYdLveiVFQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+97iT6tCGKkyCXaz6CZeuLgAA
+
+
+False
+0.523598775598299
+30
+epTail
+uYYWPxyAeUi8S962EuC1rQAA
+
+
+False
+0.523598775598299
+25
+epHead
+97iT6tCGKkyCXaz6CZeuLgAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+uYYWPxyAeUi8S962EuC1rQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+97iT6tCGKkyCXaz6CZeuLgAA
+
+
+False
+0.785398163397448
+40
+epTail
+uYYWPxyAeUi8S962EuC1rQAA
+
+
+False
+-1164
+-1160
+50
+8
+97iT6tCGKkyCXaz6CZeuLgAA
+
+
+False
+-1164
+-1160
+50
+8
+uYYWPxyAeUi8S962EuC1rQAA
+
+
+
+clMaroon
+$00B9FFFF
+160
+332
+80
+59
+False
+MinkjMMmj0WnGAFffRPN7AAA
+
+
+1
+filter
+
+
+False
+
+
+False
+
+
+
+MinkjMMmj0WnGAFffRPN7AAA
+
+
+False
+MinkjMMmj0WnGAFffRPN7AAA
+
+
+False
+MinkjMMmj0WnGAFffRPN7AAA
+
+
+
+clMaroon
+$00B9FFFF
+209,332;228,275
+False
+dm/HWW2igUWAx0IfHYYNFQAA
+PTTthVdFJkSuxFmOBKW8BQAA
+Lnqf22dPvUeqZR4EVOcXpwAA
+
+False
+1.5707963267949
+15
+dm/HWW2igUWAx0IfHYYNFQAA
+
+
+False
+1.5707963267949
+30
+dm/HWW2igUWAx0IfHYYNFQAA
+
+
+False
+-1.5707963267949
+15
+dm/HWW2igUWAx0IfHYYNFQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+LRa97zvNfE6QDL2KMnaL6AAA
+
+
+False
+0.523598775598299
+30
+epTail
+B23oUY88Cki+zVKzGFAFQwAA
+
+
+False
+0.523598775598299
+25
+epHead
+LRa97zvNfE6QDL2KMnaL6AAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+B23oUY88Cki+zVKzGFAFQwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+LRa97zvNfE6QDL2KMnaL6AAA
+
+
+False
+0.785398163397448
+40
+epTail
+B23oUY88Cki+zVKzGFAFQwAA
+
+
+False
+-1164
+-1160
+50
+8
+LRa97zvNfE6QDL2KMnaL6AAA
+
+
+False
+-1164
+-1160
+50
+8
+B23oUY88Cki+zVKzGFAFQwAA
+
+
+
+clMaroon
+$00B9FFFF
+80
+212
+80
+69
+False
+GSN9ennMhUCX9bSMU2RbvAAA
+
+
+1
+file
+
+
+False
+
+
+False
+
+
+
+GSN9ennMhUCX9bSMU2RbvAAA
+
+
+False
+GSN9ennMhUCX9bSMU2RbvAAA
+
+
+False
+GSN9ennMhUCX9bSMU2RbvAAA
+
+
+
+clMaroon
+$00B9FFFF
+159,212;210,169
+k4g3SQ7ifkqOQmiq3Ews0gAA
+g+ZdW0H0HESi/Ogvi7viDwAA
+TUke9easfU6EiMuTuB0RVgAA
+
+False
+1.5707963267949
+15
+k4g3SQ7ifkqOQmiq3Ews0gAA
+
+
+False
+1.5707963267949
+30
+k4g3SQ7ifkqOQmiq3Ews0gAA
+
+
+False
+-1.5707963267949
+15
+k4g3SQ7ifkqOQmiq3Ews0gAA
+
+
+False
+-0.523598775598299
+30
+epHead
+35JrPMkLO0Gu4ajaIH1veQAA
+
+
+False
+0.523598775598299
+30
+epTail
+dXGPheZzhEickh57kun1rQAA
+
+
+False
+0.523598775598299
+25
+epHead
+35JrPMkLO0Gu4ajaIH1veQAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+dXGPheZzhEickh57kun1rQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+35JrPMkLO0Gu4ajaIH1veQAA
+
+
+False
+0.785398163397448
+40
+epTail
+dXGPheZzhEickh57kun1rQAA
+
+
+False
+-1164
+-1160
+50
+8
+35JrPMkLO0Gu4ajaIH1veQAA
+
+
+False
+-1164
+-1160
+50
+8
+dXGPheZzhEickh57kun1rQAA
+
+
+
+clMaroon
+$00B9FFFF
+179,332;143,280
+J56fu3iSu0mLjzTyb5mWsQAA
+TUke9easfU6EiMuTuB0RVgAA
+Lnqf22dPvUeqZR4EVOcXpwAA
+
+False
+1.5707963267949
+15
+J56fu3iSu0mLjzTyb5mWsQAA
+
+
+False
+1.5707963267949
+30
+J56fu3iSu0mLjzTyb5mWsQAA
+
+
+False
+-1.5707963267949
+15
+J56fu3iSu0mLjzTyb5mWsQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+RpCKWviz/k6U/Zb0TlYL0AAA
+
+
+False
+0.523598775598299
+30
+epTail
+h36S8nlkK0O/Y12q9bev2AAA
+
+
+False
+0.523598775598299
+25
+epHead
+RpCKWviz/k6U/Zb0TlYL0AAA
+
+
+False
+-0.523598775598299
+25
+epTail
+h36S8nlkK0O/Y12q9bev2AAA
+
+
+False
+-0.785398163397448
+40
+epHead
+RpCKWviz/k6U/Zb0TlYL0AAA
+
+
+False
+0.785398163397448
+40
+epTail
+h36S8nlkK0O/Y12q9bev2AAA
+
+
+False
+-1164
+-1160
+50
+8
+RpCKWviz/k6U/Zb0TlYL0AAA
+
+
+False
+-1164
+-1160
+50
+8
+h36S8nlkK0O/Y12q9bev2AAA
+
+
+
+
+12
+
+convertprojectml
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+iv3WNEaVUkyVZFthO5NWpAAA
+6GkgL0HFhk2+4p3cHxQuuAAA
+V/OLD6PLJE2sTgoxhFPr5gAA
+GzQ90Lb030+iCObLiCouzQAA
+2
+4qk8cKW65kie31vCKuC5LQAA
+v71Cv0dawUKL+j5BmN9CRAAA
+
+
+targetProject
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+VpqNyMzcgUKFjkrP2MYKXAAA
+TFNnSzLONkCG5/BpZAIeagAA
+NH0nETVU0EuJ6Z9Cz48x5QAA
+cxcTAxaEb0WAQVOnN9psUQAA
+1
+2+NhaybpyE+grJZ6zRo07AAA
+2
+
+path
+Bd5einjYSUuwBOyRucxDOgAA
+
+
+name
+Bd5einjYSUuwBOyRucxDOgAA
+
+
+
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+/fCBgmCAk0CO4akmTB9asAAA
+FXBHUSeK9Ui4mcgWsbLx9QAA
+0qBBdcCSTUGu/+qWzhDm3gAA
+6lcCKGyeb0G994ykTac1FwAA
+2
+
+1
+A6cb4Q7lhEuoG/7OMN+p9wAA
+Bd5einjYSUuwBOyRucxDOgAA
+4
+D0TN80bW5EOQFb5Q7OrWuwAA
+UMxDUG68zkybuet7LtcblAAA
+ovkjWz6hFUSm3YE1E6gPPwAA
+uUkbFBONiEK4tQ8+jvGOagAA
+
+
+akAggregate
+A6cb4Q7lhEuoG/7OMN+p9wAA
+pY4k1EkTmk6ZYPgvdrAXtgAA
+4
+UEiwJZuxV0qiwEruVB/fagAA
+VK5ZX7eD/0SyDw7Eufj4vQAA
+cLLDfyut6kGwvf6NUeypKQAA
+JfOr8liXA0SDPav6llhs0QAA
+
+
+
+layer
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+g+ZdW0H0HESi/Ogvi7viDwAA
+FH8AkyxL5EOCX+BYa6SrlgAA
+USFNUNhmj0yH1SvfBQEQrQAA
+qJCGu3GWKEC7Mr7Bh0/wFQAA
+3
+e3mjKSqfHkG5KNzBPWb2xgAA
+97iT6tCGKkyCXaz6CZeuLgAA
+35JrPMkLO0Gu4ajaIH1veQAA
+1
+
+path
+8tRKm9V57EqPhwTgLVrWPgAA
+
+
+
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+Se3ExbwAX0azxiV+lhbH1QAA
+vkZ0Fv4Bn0W41OB6HQavDgAA
+LQR6UWHc4Ea3gcYRzo4rtQAA
+utBA13fqHEmyRaVuabIumAAA
+2
+
+1..*
+SSk55GHANUS/X4vl9shC8QAA
+8tRKm9V57EqPhwTgLVrWPgAA
+4
+z/UH4Q3Z4EWHKaaR8vvtfQAA
+MqHBFuNZcU2QxpK7I4i2AAAA
+B3JM9SfN6UOJHoBOPeLOXwAA
+IVcwoQfX5kuC26wihsMOGgAA
+
+
+akAggregate
+SSk55GHANUS/X4vl9shC8QAA
+pY4k1EkTmk6ZYPgvdrAXtgAA
+4
+vXzjhvstTkSYH5e+JqNO3QAA
+X5PozNl5cEauMneuFrs07wAA
+4m8gx9uY6U2rKOpnM2P+DQAA
+LLo+exIB20+Y44xBRPncQAAA
+
+
+
+folder
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+PTTthVdFJkSuxFmOBKW8BQAA
+9bTnu14KsU+bjx01kQjXkQAA
+GmVBBTyRTUm5aydZhl8uiQAA
+gbWtSI5IL0yQ4YixznRTJwAA
+2
+uYYWPxyAeUi8S962EuC1rQAA
+LRa97zvNfE6QDL2KMnaL6AAA
+1
+
+path
+NcePGMdhZE+ri6hKbPWURgAA
+
+
+
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+Lh/iX7FeqUC6HaaNzKIcAAAA
+tARUeKesG0+P0dqfJYtPngAA
+cXj6zgnDdUS5eb0jbzEIwAAA
+xmSD+TyyiUqlg5UifHLqwgAA
+2
+
+0..*
+GlHcJZ4KsUGJaYdLveiVFQAA
+NcePGMdhZE+ri6hKbPWURgAA
+4
+JRjeqlUrOEaICyTmumrkZAAA
+8w3hAl+aLUGxp4MbOogPpwAA
+q1V84zM0+UiTJRerY/Zb9gAA
+9R4PmO7klkiCMDymCJSl8gAA
+
+
+akAggregate
+GlHcJZ4KsUGJaYdLveiVFQAA
+8tRKm9V57EqPhwTgLVrWPgAA
+4
+g56+K6gaJUCXbCCDMD3yrgAA
+85EuFW2/n0u7Rs1KNL8DcwAA
+RmHhCI+6KEqr131Pp66AAAAA
+HTJUbsD9PUmlo9tEtonI4QAA
+
+
+
+filter
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+Lnqf22dPvUeqZR4EVOcXpwAA
+Q00ZOYiNLk6FMB7Q9Ph3VQAA
+EcTlqk+l0EiCdWtDxdyvKwAA
+yHyE5XoFYE+c9l9cF248ZAAA
+2
+B23oUY88Cki+zVKzGFAFQwAA
+h36S8nlkK0O/Y12q9bev2AAA
+2
+
+action
+MinkjMMmj0WnGAFffRPN7AAA
+
+
+data
+MinkjMMmj0WnGAFffRPN7AAA
+
+
+
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+YjtBOo0EJ0+pt6FGBWw+IQAA
+4ii7MCdDxECAqwVSN/izogAA
+O+wIAw6nZUuvJSFD4dPvzwAA
+LYAMaqZWTkidLQY+56mMwAAA
+2
+
+0..*
+dm/HWW2igUWAx0IfHYYNFQAA
+MinkjMMmj0WnGAFffRPN7AAA
+4
+gEA67EMVs0awcRlwAk8r1wAA
+Asccy8b6nUKktHBeNPW/ogAA
+GGyyfQFqAkCqRB4ixaIO5QAA
+G//iq2AzQEqzixTcs5y4NgAA
+
+
+akAggregate
+dm/HWW2igUWAx0IfHYYNFQAA
+NcePGMdhZE+ri6hKbPWURgAA
+4
+TwxQlo6YgUSxOSvOowV3SQAA
+oz+AsvXI8k6sSenEMRIMwAAA
+GceYc3HbukmueOkr4LlLVwAA
+I9iPInyOo0O8lKR7r0/CRAAA
+
+
+
+file
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+TUke9easfU6EiMuTuB0RVgAA
+XPOeAYVXIUecTeVh8nZf/gAA
+17HZGDoEvkKQvOS9iEoHZAAA
+ULFpJlTs30ib6+JsymDRJgAA
+2
+dXGPheZzhEickh57kun1rQAA
+RpCKWviz/k6U/Zb0TlYL0AAA
+2
+
+type
+GSN9ennMhUCX9bSMU2RbvAAA
+
+
+path
+GSN9ennMhUCX9bSMU2RbvAAA
+
+
+
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+Y2oggBOnQ0mTJTq1W/N5NQAA
+75mbZhUHuUy+I+SUrwHP7AAA
+A6S7do0+ikSpnXpUrpSZSQAA
+hSHjElEcQU+vPwfY9Wv5OwAA
+2
+
+0..*
+k4g3SQ7ifkqOQmiq3Ews0gAA
+GSN9ennMhUCX9bSMU2RbvAAA
+4
+Xkj3BF+LL0eEOwn9mDCMsQAA
+V8jzTvOiVkaX2OdcsoWdOAAA
+IDlxkebmR0KLVuWoA+eg1wAA
+Bz0v56MxlkOMYPoMFG2ljAAA
+
+
+akAggregate
+k4g3SQ7ifkqOQmiq3Ews0gAA
+8tRKm9V57EqPhwTgLVrWPgAA
+4
+bzv1AIGxqUe1OZUf2khOTgAA
+qjXGDJbOmkWR5aVjMYp/pAAA
+WBQbtXOaVEa72Rwy5EsQiwAA
+qz3x7XlZCEmqYD9lMYn43QAA
+
+
+
+dJLeoE8dBU6wuilHUj+y3gAA
+4
+L1P6nujprEiF4AEy6WsBlQAA
+MVgXXDXydEmyC+X+9tYa6wAA
+Kzv9UMT4DUyxMMJHwH2/HQAA
+81dN834u0kWtQhb/ahuVuAAA
+2
+
+J56fu3iSu0mLjzTyb5mWsQAA
+MinkjMMmj0WnGAFffRPN7AAA
+4
+MwIsbjaQZkmapb3k7bQUzAAA
+Xsf4ZsEsLUec441Bzjng1wAA
+ubv5ve55f0Kktu9yQ2P3jAAA
+4G2vvqboTEO7IXr3DavvqAAA
+
+
+akAggregate
+J56fu3iSu0mLjzTyb5mWsQAA
+GSN9ennMhUCX9bSMU2RbvAAA
+4
+Ttzz8EY52U+59ICd4dk+lAAA
+x8+dMKRJBka8hb42W2vRiwAA
+sc6SVZ+Vg0G0J6W8+/CvdQAA
+wKXgxL2co0uBDUhw1ZMX+QAA
+
+
+
+
+templateml
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+templateml
+NBOnOHSop0qGcP1sMvuIqQAA
+
+1tS2Rly7fkeaiJArnuzjggAA
+8
+
+clMaroon
+$00B9FFFF
+108
+12
+101
+43
+False
+ZZqfHIjqoES//zvmLYmGvQAA
+
+
+1
+templateml
+
+
+False
+
+
+False
+
+
+
+ZZqfHIjqoES//zvmLYmGvQAA
+
+
+False
+ZZqfHIjqoES//zvmLYmGvQAA
+
+
+False
+ZZqfHIjqoES//zvmLYmGvQAA
+
+
+
+clMaroon
+$00B9FFFF
+24
+124
+90
+82
+False
+HmWD/itgh0y3rMseN13BUgAA
+
+
+1
+output
+
+
+False
+
+
+False
+
+
+
+HmWD/itgh0y3rMseN13BUgAA
+
+
+False
+HmWD/itgh0y3rMseN13BUgAA
+
+
+False
+HmWD/itgh0y3rMseN13BUgAA
+
+
+
+clMaroon
+$00B9FFFF
+95,124;143,54
+False
+A1nvBhHM00+kYXoRN/m94gAA
+U1r4twqdtE+71hOpS9c6sAAA
+OhfpUSWcwEes0nqeEAqNMgAA
+
+False
+1.5707963267949
+15
+A1nvBhHM00+kYXoRN/m94gAA
+
+
+False
+1.5707963267949
+30
+A1nvBhHM00+kYXoRN/m94gAA
+
+
+False
+-1.5707963267949
+15
+A1nvBhHM00+kYXoRN/m94gAA
+
+
+False
+-0.523598775598299
+30
+epHead
+VkpSC2YwLEqelxDb3MRkbAAA
+
+
+False
+0.523598775598299
+30
+epTail
+p8U+8eh9YEu7vfqSGdIDQwAA
+
+
+False
+0.523598775598299
+25
+epHead
+VkpSC2YwLEqelxDb3MRkbAAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+p8U+8eh9YEu7vfqSGdIDQwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+VkpSC2YwLEqelxDb3MRkbAAA
+
+
+False
+0.785398163397448
+40
+epTail
+p8U+8eh9YEu7vfqSGdIDQwAA
+
+
+False
+-1064
+-1140
+50
+8
+VkpSC2YwLEqelxDb3MRkbAAA
+
+
+False
+-1064
+-1140
+50
+8
+p8U+8eh9YEu7vfqSGdIDQwAA
+
+
+
+clMaroon
+$00B9FFFF
+176
+136
+86
+59
+False
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+
+
+1
+filter
+
+
+False
+
+
+False
+
+
+
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+
+
+False
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+
+
+False
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+
+
+
+clMaroon
+$00B9FFFF
+205,136;168,54
+False
+aKV3lamzTUOWSLJLamrmZgAA
+U1r4twqdtE+71hOpS9c6sAAA
+/WUCCxjEGkKy+g9J7mc5hgAA
+
+False
+1.5707963267949
+15
+aKV3lamzTUOWSLJLamrmZgAA
+
+
+False
+1.5707963267949
+30
+aKV3lamzTUOWSLJLamrmZgAA
+
+
+False
+-1.5707963267949
+15
+aKV3lamzTUOWSLJLamrmZgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+Wg6dzEuNJEWFxVFa578pzgAA
+
+
+False
+0.523598775598299
+30
+epTail
+fnL+Az0cLkG7ny/btlA/nQAA
+
+
+False
+0.523598775598299
+25
+epHead
+Wg6dzEuNJEWFxVFa578pzgAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+fnL+Az0cLkG7ny/btlA/nQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+Wg6dzEuNJEWFxVFa578pzgAA
+
+
+False
+0.785398163397448
+40
+epTail
+fnL+Az0cLkG7ny/btlA/nQAA
+
+
+False
+-1064
+-1140
+50
+8
+Wg6dzEuNJEWFxVFa578pzgAA
+
+
+False
+-1064
+-1140
+50
+8
+fnL+Az0cLkG7ny/btlA/nQAA
+
+
+
+clMaroon
+$00B9FFFF
+28
+268
+80
+46
+False
+62pu/fhna0alwjKTg6UxrgAA
+
+
+1
+template
+
+
+False
+
+
+False
+
+
+
+62pu/fhna0alwjKTg6UxrgAA
+
+
+False
+62pu/fhna0alwjKTg6UxrgAA
+
+
+False
+62pu/fhna0alwjKTg6UxrgAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+68,268;68,205
+False
+J8S7UzExwUe/hB627vCc2AAA
+OhfpUSWcwEes0nqeEAqNMgAA
+wLwFsbh+D06trOxi89tn3QAA
+
+False
+1.5707963267949
+15
+J8S7UzExwUe/hB627vCc2AAA
+
+
+False
+1.5707963267949
+30
+J8S7UzExwUe/hB627vCc2AAA
+
+
+False
+-1.5707963267949
+15
+J8S7UzExwUe/hB627vCc2AAA
+
+
+False
+-0.523598775598299
+30
+epHead
+JE4UMolSLUCkhgzIjPusxgAA
+
+
+False
+0.523598775598299
+30
+epTail
+fqzkaBDTOkWXymGMvmkWpQAA
+
+
+False
+0.523598775598299
+25
+epHead
+JE4UMolSLUCkhgzIjPusxgAA
+
+
+-0.523598775598299
+25
+epTail
+1
+fqzkaBDTOkWXymGMvmkWpQAA
+
+
+False
+-0.785398163397448
+40
+epHead
+JE4UMolSLUCkhgzIjPusxgAA
+
+
+False
+0.785398163397448
+40
+epTail
+fqzkaBDTOkWXymGMvmkWpQAA
+
+
+False
+-1064
+-1140
+50
+8
+JE4UMolSLUCkhgzIjPusxgAA
+
+
+False
+-1064
+-1140
+50
+8
+fqzkaBDTOkWXymGMvmkWpQAA
+
+
+
+clMaroon
+$00B9FFFF
+lsRectilinear
+176,165;113,165
+False
+i0gr6XmS8E2A1MzxSYycBgAA
+OhfpUSWcwEes0nqeEAqNMgAA
+/WUCCxjEGkKy+g9J7mc5hgAA
+
+False
+1.5707963267949
+15
+i0gr6XmS8E2A1MzxSYycBgAA
+
+
+False
+1.5707963267949
+30
+i0gr6XmS8E2A1MzxSYycBgAA
+
+
+False
+-1.5707963267949
+15
+i0gr6XmS8E2A1MzxSYycBgAA
+
+
+False
+-0.523598775598299
+30
+epHead
+qpJxc0PXGkyV1V6W0racVwAA
+
+
+False
+0.523598775598299
+30
+epTail
+K5dsg2gf9kyvrWslEbV/QgAA
+
+
+False
+0.523598775598299
+25
+epHead
+qpJxc0PXGkyV1V6W0racVwAA
+
+
+-0.523598775598299
+25
+epTail
+0..*
+K5dsg2gf9kyvrWslEbV/QgAA
+
+
+False
+-0.785398163397448
+40
+epHead
+qpJxc0PXGkyV1V6W0racVwAA
+
+
+False
+0.785398163397448
+40
+epTail
+K5dsg2gf9kyvrWslEbV/QgAA
+
+
+False
+-1064
+-1140
+50
+8
+qpJxc0PXGkyV1V6W0racVwAA
+
+
+False
+-1064
+-1140
+50
+8
+K5dsg2gf9kyvrWslEbV/QgAA
+
+
+
+
+8
+
+templateml
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+U1r4twqdtE+71hOpS9c6sAAA
+LVdRWi1iH0OtdwU8dffOYgAA
+hXenmLyknUmGK8tw6YzZjQAA
+pViY1MZuNkSbcz+EvsaSIAAA
+2
+VkpSC2YwLEqelxDb3MRkbAAA
+Wg6dzEuNJEWFxVFa578pzgAA
+
+
+output
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+OhfpUSWcwEes0nqeEAqNMgAA
+xTtj+2BgCUaJGfXDE4epKgAA
+5T5QIJs5bkC3yFRHD+CS3gAA
+Q5IVhcazmkeovkvlbY+7gAAA
+3
+p8U+8eh9YEu7vfqSGdIDQwAA
+JE4UMolSLUCkhgzIjPusxgAA
+qpJxc0PXGkyV1V6W0racVwAA
+3
+
+file
+HmWD/itgh0y3rMseN13BUgAA
+
+
+encoding
+HmWD/itgh0y3rMseN13BUgAA
+
+
+dir
+HmWD/itgh0y3rMseN13BUgAA
+
+
+
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+QTh97p8rQkKdA6/nPPCCOAAA
+EhE6sNZekEWoEMy8Bd+M1gAA
+mU0wtyD+3kCN+W194GZOHQAA
+aRHEKIfKo0S6iBJ1ykt1OAAA
+2
+
+0..*
+A1nvBhHM00+kYXoRN/m94gAA
+HmWD/itgh0y3rMseN13BUgAA
+4
+jaK0YKFkUUufuE1bN5mg6AAA
+d3sRf7EUbEOYq9oSMPniQwAA
+08gFHdTU7Eu73RKfKRuICwAA
+Ws91SXD/3ECAejMthIpPIQAA
+
+
+akAggregate
+A1nvBhHM00+kYXoRN/m94gAA
+ZZqfHIjqoES//zvmLYmGvQAA
+4
+qCOzbMssm0q4DHiI1Be8YgAA
+FvAf8GPhyEKfv7wyV3MyqAAA
+uTzQ5W67IUa+s0DysLvqcAAA
+tVphH9XkO0GwweAEJtO4JwAA
+
+
+
+filter
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+/WUCCxjEGkKy+g9J7mc5hgAA
+cOkP/ZDLd0WR/bhe2mHrGAAA
+bx3/IIWKoU6ssJVLpr0IjwAA
+n8q1I0IwC0KSCpOC4GvUBQAA
+2
+fnL+Az0cLkG7ny/btlA/nQAA
+K5dsg2gf9kyvrWslEbV/QgAA
+2
+
+name
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+
+
+file
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+
+
+
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+/XcOpl6Eakq9m3pREzu2qgAA
+8A+IJWuUZECFDK8+ROtirQAA
+y2tg1tZQREa1mE1Bhanz1QAA
+pqpwqQc5FEm3M4QjeEtmkwAA
+2
+
+0..*
+aKV3lamzTUOWSLJLamrmZgAA
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+4
+tIq0+N/SMEWS7Ul9hUgAIwAA
+Uf6u9IJwmEetzhAnYu34RwAA
+Mn1ysS8ZH0e91EC1bKYIVQAA
+hJB7vnssxU6XBUKdZH906wAA
+
+
+akAggregate
+aKV3lamzTUOWSLJLamrmZgAA
+ZZqfHIjqoES//zvmLYmGvQAA
+4
+FIDSh1RQYkqNGRJAqMGHQAAA
+xIQ5HmOlHk2wF2lSey1lfAAA
+Lo+LK5HzZUWe66RLyHRjHQAA
+NCzGopwd1EyU2Ii4xVWsZQAA
+
+
+
+template
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+wLwFsbh+D06trOxi89tn3QAA
+FDzG0KM06UiF3jchy3fdbQAA
+1PCwzXhrn0GqIHSHgKvqXgAA
+LoFXPjHYJEq9GA0ynoRJkAAA
+1
+fqzkaBDTOkWXymGMvmkWpQAA
+1
+
+file
+62pu/fhna0alwjKTg6UxrgAA
+
+
+
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+jcovGPVQI0GxHprQUKJgSQAA
+7hlkM0b0uE6lAbNPX2DPCgAA
+vNb1nL8N70+WUu7ldlU4ZQAA
+x5H+UXze7USmBJWDOZbvjAAA
+2
+
+1
+J8S7UzExwUe/hB627vCc2AAA
+62pu/fhna0alwjKTg6UxrgAA
+4
+BOzMiL32Sk+Y7NTaTQSFuQAA
+vogdshwKAk+g75I3DUPZYwAA
+QB70zNO4iEipl2M2cwA4pQAA
+o09/ZLSLA0CIuhO1WTv0oAAA
+
+
+akAggregate
+J8S7UzExwUe/hB627vCc2AAA
+HmWD/itgh0y3rMseN13BUgAA
+4
+Pvjs451lBUmXyIiNz25/owAA
+HD0dWWNupk+4YB2bF7uVjwAA
+qH29/3IAg0OK800Zst2o8gAA
+HNWZYjgXWEmpaaZwzOH0agAA
+
+
+
+NBOnOHSop0qGcP1sMvuIqQAA
+4
+Bxm0PcO3HkGzYIa/07SA+QAA
+zlHXniU8HkWXeXAvi8LC3wAA
+iqQ2fTYWCk2bVl0V8L8bAQAA
+qkJEISgeakevZZjEoEYYZwAA
+2
+
+0..*
+i0gr6XmS8E2A1MzxSYycBgAA
+Xhfbq+Z8AkehSoc9Hm/TFQAA
+4
+oMFnGwPi3EWXGH6rFNCaVQAA
++cSNeipqp0O4evP77LJR8wAA
+1loZyamgOky2w3Y+/JUNMAAA
+Gefp+1/1ZUK9l9a5GSta9gAA
+
+
+akAggregate
+i0gr6XmS8E2A1MzxSYycBgAA
+HmWD/itgh0y3rMseN13BUgAA
+4
+OJhw/l7OF0KqUw32zCJohQAA
+qPXhNcsZ8kywAauSvgVxLQAA
+t3C2Ivb82Eqy6kEX7PkV+gAA
+KjYuXW8P7UmFm4NiMC/GJQAA
+
+
+
+
+thememl
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+thememl
+AXaa4fXnMkSQbYhO++BySwAA
+
+dsXIkwC9eUGhfkNKhAbscwAA
+11
+
+clMaroon
+$00B9FFFF
+124
+24
+86
+43
+False
+E1iu90tl5UOMzz4DqQdgKgAA
+
+
+1
+thememl
+
+
+False
+
+
+False
+
+
+
+E1iu90tl5UOMzz4DqQdgKgAA
+
+
+False
+E1iu90tl5UOMzz4DqQdgKgAA
+
+
+False
+E1iu90tl5UOMzz4DqQdgKgAA
+
+
+
+clMaroon
+$00B9FFFF
+32
+132
+91
+43
+False
+bW6r62dSEEmci8YVu/j1+AAA
+
+
+1
+carbideuiPath
+
+
+False
+
+
+False
+
+
+
+bW6r62dSEEmci8YVu/j1+AAA
+
+
+False
+bW6r62dSEEmci8YVu/j1+AAA
+
+
+False
+bW6r62dSEEmci8YVu/j1+AAA
+
+
+
+clMaroon
+$00B9FFFF
+136
+132
+86
+43
+False
+LCO1bffXG0OrOxRw0E8QrQAA
+
+
+1
+themeDir
+
+
+False
+
+
+False
+
+
+
+LCO1bffXG0OrOxRw0E8QrQAA
+
+
+False
+LCO1bffXG0OrOxRw0E8QrQAA
+
+
+False
+LCO1bffXG0OrOxRw0E8QrQAA
+
+
+
+clMaroon
+$00B9FFFF
+256
+136
+84
+43
+False
+2bjs9/U4tkC8lb+E9SbivwAA
+
+
+1
+activeTheme
+
+
+False
+
+
+False
+
+
+
+2bjs9/U4tkC8lb+E9SbivwAA
+
+
+False
+2bjs9/U4tkC8lb+E9SbivwAA
+
+
+False
+2bjs9/U4tkC8lb+E9SbivwAA
+
+
+
+clMaroon
+$00B9FFFF
+94,132;149,66
+False
+31v9Omcga0SIleb9L/1ClQAA
+mhHfj6aZiUChhByPx5R1JwAA
+zd6x5YWqzEazqG7OYjf4/wAA
+
+False
+1.5707963267949
+15
+31v9Omcga0SIleb9L/1ClQAA
+
+
+False
+1.5707963267949
+30
+31v9Omcga0SIleb9L/1ClQAA
+
+
+False
+-1.5707963267949
+15
+31v9Omcga0SIleb9L/1ClQAA
+
+
+False
+-0.523598775598299
+30
+epHead
+wcsyP+nnQUKjH0wjScVReAAA
+
+
+False
+0.523598775598299
+30
+epTail
+6zS16THhTkGwS65tWjQZCAAA
+
+
+False
+0.523598775598299
+25
+epHead
+wcsyP+nnQUKjH0wjScVReAAA
+
+
+False
+-0.523598775598299
+25
+epTail
+6zS16THhTkGwS65tWjQZCAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+wcsyP+nnQUKjH0wjScVReAAA
+
+
+False
+0.785398163397448
+40
+epTail
+6zS16THhTkGwS65tWjQZCAAA
+
+
+False
+-1188
+-1100
+50
+8
+wcsyP+nnQUKjH0wjScVReAAA
+
+
+False
+-1188
+-1100
+50
+8
+6zS16THhTkGwS65tWjQZCAAA
+
+
+
+clMaroon
+$00B9FFFF
+176,132;168,66
+False
+OImmNP8TaU2uwE/LH3/DiAAA
+mhHfj6aZiUChhByPx5R1JwAA
+NAew17kPWEus8PVpRLBxgwAA
+
+False
+1.5707963267949
+15
+OImmNP8TaU2uwE/LH3/DiAAA
+
+
+False
+1.5707963267949
+30
+OImmNP8TaU2uwE/LH3/DiAAA
+
+
+False
+-1.5707963267949
+15
+OImmNP8TaU2uwE/LH3/DiAAA
+
+
+False
+-0.523598775598299
+30
+epHead
+YntvV5hUUUKJJTQuPjiKKwAA
+
+
+False
+0.523598775598299
+30
+epTail
+/KYpV/ZNd0664wj7eL8/lwAA
+
+
+False
+0.523598775598299
+25
+epHead
+YntvV5hUUUKJJTQuPjiKKwAA
+
+
+False
+-0.523598775598299
+25
+epTail
+/KYpV/ZNd0664wj7eL8/lwAA
+
+
+False
+-0.785398163397448
+40
+epHead
+YntvV5hUUUKJJTQuPjiKKwAA
+
+
+False
+0.785398163397448
+40
+epTail
+/KYpV/ZNd0664wj7eL8/lwAA
+
+
+False
+-1188
+-1100
+50
+8
+YntvV5hUUUKJJTQuPjiKKwAA
+
+
+False
+-1188
+-1100
+50
+8
+/KYpV/ZNd0664wj7eL8/lwAA
+
+
+
+clMaroon
+$00B9FFFF
+272,136;190,66
+False
+cwzTm4JdpEaerFvN+5vV6QAA
+mhHfj6aZiUChhByPx5R1JwAA
+k+BoKCtq1kuPCID2EqWPRQAA
+
+False
+1.5707963267949
+15
+cwzTm4JdpEaerFvN+5vV6QAA
+
+
+False
+1.5707963267949
+30
+cwzTm4JdpEaerFvN+5vV6QAA
+
+
+False
+-1.5707963267949
+15
+cwzTm4JdpEaerFvN+5vV6QAA
+
+
+False
+-0.523598775598299
+30
+epHead
+DHEqz/kumEqKpEuG6SZp0wAA
+
+
+False
+0.523598775598299
+30
+epTail
+buExkO5cRkKq6ABkiq0yKAAA
+
+
+False
+0.523598775598299
+25
+epHead
+DHEqz/kumEqKpEuG6SZp0wAA
+
+
+False
+-0.523598775598299
+25
+epTail
+buExkO5cRkKq6ABkiq0yKAAA
+
+
+False
+-0.785398163397448
+40
+epHead
+DHEqz/kumEqKpEuG6SZp0wAA
+
+
+False
+0.785398163397448
+40
+epTail
+buExkO5cRkKq6ABkiq0yKAAA
+
+
+False
+-1188
+-1100
+50
+8
+DHEqz/kumEqKpEuG6SZp0wAA
+
+
+False
+-1188
+-1100
+50
+8
+buExkO5cRkKq6ABkiq0yKAAA
+
+
+
+clMaroon
+$00B9FFFF
+212
+248
+80
+43
+False
+PcWGUaK8Z0qAqZHa1Kx3UQAA
+
+
+1
+refSetting
+
+
+False
+
+
+False
+
+
+
+PcWGUaK8Z0qAqZHa1Kx3UQAA
+
+
+False
+PcWGUaK8Z0qAqZHa1Kx3UQAA
+
+
+False
+PcWGUaK8Z0qAqZHa1Kx3UQAA
+
+
+
+clMaroon
+$00B9FFFF
+260,248;288,178
+False
+en8FxQY7BE+v9p/cI6Vh9wAA
+k+BoKCtq1kuPCID2EqWPRQAA
+kvcaM+qeN0Wl35tMVddpygAA
+
+False
+1.5707963267949
+15
+en8FxQY7BE+v9p/cI6Vh9wAA
+
+
+False
+1.5707963267949
+30
+en8FxQY7BE+v9p/cI6Vh9wAA
+
+
+False
+-1.5707963267949
+15
+en8FxQY7BE+v9p/cI6Vh9wAA
+
+
+False
+-0.523598775598299
+30
+epHead
+5vqtzQAgIk2Fz0Fh7XaBfQAA
+
+
+False
+0.523598775598299
+30
+epTail
+nEZrS2XOiE6AMkRarVVpLgAA
+
+
+False
+0.523598775598299
+25
+epHead
+5vqtzQAgIk2Fz0Fh7XaBfQAA
+
+
+False
+-0.523598775598299
+25
+epTail
+nEZrS2XOiE6AMkRarVVpLgAA
+
+
+False
+-0.785398163397448
+40
+epHead
+5vqtzQAgIk2Fz0Fh7XaBfQAA
+
+
+False
+0.785398163397448
+40
+epTail
+nEZrS2XOiE6AMkRarVVpLgAA
+
+
+False
+-1188
+-1100
+50
+8
+5vqtzQAgIk2Fz0Fh7XaBfQAA
+
+
+False
+-1188
+-1100
+50
+8
+nEZrS2XOiE6AMkRarVVpLgAA
+
+
+
+clMaroon
+$00B9FFFF
+320
+248
+101
+43
+False
+3n6KakpGs0aeHYe1gxZ0PwAA
+
+
+1
+platformUID
+
+
+False
+
+
+False
+
+
+
+3n6KakpGs0aeHYe1gxZ0PwAA
+
+
+False
+3n6KakpGs0aeHYe1gxZ0PwAA
+
+
+False
+3n6KakpGs0aeHYe1gxZ0PwAA
+
+
+
+clMaroon
+$00B9FFFF
+356,248;311,178
+False
+WUcaNoS+W0ScfGgjVLs+nAAA
+k+BoKCtq1kuPCID2EqWPRQAA
+7IwNs/XM5kq9sOavQnifWwAA
+
+False
+1.5707963267949
+15
+WUcaNoS+W0ScfGgjVLs+nAAA
+
+
+False
+1.5707963267949
+30
+WUcaNoS+W0ScfGgjVLs+nAAA
+
+
+False
+-1.5707963267949
+15
+WUcaNoS+W0ScfGgjVLs+nAAA
+
+
+False
+-0.523598775598299
+30
+epHead
+HH2WAgAA0k2bTYjARMIr8gAA
+
+
+False
+0.523598775598299
+30
+epTail
+gl2nXNPFBUKFkpD9Y+jkywAA
+
+
+False
+0.523598775598299
+25
+epHead
+HH2WAgAA0k2bTYjARMIr8gAA
+
+
+False
+-0.523598775598299
+25
+epTail
+gl2nXNPFBUKFkpD9Y+jkywAA
+
+
+False
+-0.785398163397448
+40
+epHead
+HH2WAgAA0k2bTYjARMIr8gAA
+
+
+False
+0.785398163397448
+40
+epTail
+gl2nXNPFBUKFkpD9Y+jkywAA
+
+
+False
+-1188
+-1100
+50
+8
+HH2WAgAA0k2bTYjARMIr8gAA
+
+
+False
+-1188
+-1100
+50
+8
+gl2nXNPFBUKFkpD9Y+jkywAA
+
+
+
+
+11
+
+thememl
+AXaa4fXnMkSQbYhO++BySwAA
+4
+mhHfj6aZiUChhByPx5R1JwAA
+F+df4ro24kugCVNjAI4JkAAA
+3TTpSy5M+060wJn6+FGJHwAA
+37T5NgO9l0eDz7mms8wc8QAA
+3
+wcsyP+nnQUKjH0wjScVReAAA
+YntvV5hUUUKJJTQuPjiKKwAA
+DHEqz/kumEqKpEuG6SZp0wAA
+
+
+carbideuiPath
+AXaa4fXnMkSQbYhO++BySwAA
+4
+zd6x5YWqzEazqG7OYjf4/wAA
+xqKFdQxjVkiB260Xy3hJngAA
+u4CP0jn930GoXG8JvYZMDwAA
+9dSAAZCioE2lQu+Hyq3a8QAA
+1
+6zS16THhTkGwS65tWjQZCAAA
+
+
+themeDir
+AXaa4fXnMkSQbYhO++BySwAA
+4
+NAew17kPWEus8PVpRLBxgwAA
+J10h/JJFOkqlnMuNlomxfgAA
+8kT61YNvQUqAEqoon8GJlgAA
+QccIyLf0pkan4beJZF0xwgAA
+1
+/KYpV/ZNd0664wj7eL8/lwAA
+
+
+activeTheme
+AXaa4fXnMkSQbYhO++BySwAA
+4
+k+BoKCtq1kuPCID2EqWPRQAA
+KAiz8RKnL0qcOnrl0aro1QAA
+wd5a4GlZ70+Cokyt15d6DQAA
+gaQqU+stC0SwxrmuQPA47AAA
+3
+buExkO5cRkKq6ABkiq0yKAAA
+5vqtzQAgIk2Fz0Fh7XaBfQAA
+HH2WAgAA0k2bTYjARMIr8gAA
+
+
+AXaa4fXnMkSQbYhO++BySwAA
+4
+UmtO+l5gk02eqTxal68NEgAA
+JRZ8C1xd2EqgtNxwQp8nRQAA
+jrPqKqz5AE6Akst2foJ6nAAA
+FtvzpDgGNUSgrrsNCw75HwAA
+2
+
+31v9Omcga0SIleb9L/1ClQAA
+bW6r62dSEEmci8YVu/j1+AAA
+4
+91T39LDFOUCfdgtQ8b0FBwAA
+UxNdyZHbo0uFVzRrAJ0wJQAA
+l6TAszl58ECFG/bqul3hTgAA
+VwOsLa+GL0uYCo2aee42tQAA
+
+
+akAggregate
+31v9Omcga0SIleb9L/1ClQAA
+E1iu90tl5UOMzz4DqQdgKgAA
+4
+rgACMezpx06NC+uElqI8OAAA
+bji12pdW0kyQut+E4yL1TQAA
+AjeuIq1FqUutfBdh8TR67AAA
+kNN5vQrcukewuz+MSve0fQAA
+
+
+
+AXaa4fXnMkSQbYhO++BySwAA
+4
+oDmUyp5ZukCAMQ30G3YWsgAA
+hohK+vYmzE2c3CV5vDVYlgAA
+Ke2HfdW0ukq0+nCL4ckZvwAA
+VUrmg0rfqUqigRm6tJf3EwAA
+2
+
+OImmNP8TaU2uwE/LH3/DiAAA
+LCO1bffXG0OrOxRw0E8QrQAA
+4
+Dn9xo4in2kScOlx5voNCnAAA
+woDMTT0EXUKqDYyuxIfuFwAA
+STejq31rzEaS1ZPocsSb8QAA
+i9SHgNaJF0qEA9zd9TRoAAAA
+
+
+akAggregate
+OImmNP8TaU2uwE/LH3/DiAAA
+E1iu90tl5UOMzz4DqQdgKgAA
+4
+fQpewNdnSUyM1sB8t3JXHgAA
+x9Nlzi/bBk6MYpa2pBJ09gAA
+uIKzgAPzf0mGGMXcEwjCFAAA
+E0Va2COtt0mAIi3iuoZ+GQAA
+
+
+
+AXaa4fXnMkSQbYhO++BySwAA
+4
+JIfYu1MCjUu32qryaGlFcgAA
+wTTvCzCBp0CWh8y8fOjWlgAA
+W3WXsmgrNUaFnzM6OKbh1wAA
+7kk+toAuYUejpPPeJZcnxQAA
+2
+
+cwzTm4JdpEaerFvN+5vV6QAA
+2bjs9/U4tkC8lb+E9SbivwAA
+4
+h8ktZnWArE2lUGGiikK6HgAA
+HYtqXSYOykm9EHCY9FK34gAA
+Ap86LOy7dk2sgzvamgQ5OAAA
++nF9DqCQ00GaV/MeLotB4wAA
+
+
+akAggregate
+cwzTm4JdpEaerFvN+5vV6QAA
+E1iu90tl5UOMzz4DqQdgKgAA
+4
+CtFyPrHRFU220NwwMYJiNAAA
+hSTeJtccQk6XhwANh6uvJAAA
+gBUIg2VKoEG9JY+xmDX9rwAA
+jnvwNeHBokiwX8NIOwEdPgAA
+
+
+
+refSetting
+AXaa4fXnMkSQbYhO++BySwAA
+4
+kvcaM+qeN0Wl35tMVddpygAA
+XCrsD/viGUK9QLWi6/a/iAAA
+AWr9XT7TL0SToL/ztqwwPQAA
+mAk4R+yKvUqjzliSa6VXMAAA
+1
+nEZrS2XOiE6AMkRarVVpLgAA
+
+
+AXaa4fXnMkSQbYhO++BySwAA
+4
+goeiQAhMAU+BS72puYAnhAAA
+hHNbId2yAUOOhXAX9Yl5SgAA
+lk8fI34YekiLrfRNR0q0AwAA
+4o7B6KUU3U2vZ6s2bK51PAAA
+2
+
+en8FxQY7BE+v9p/cI6Vh9wAA
+PcWGUaK8Z0qAqZHa1Kx3UQAA
+4
+T+nvbA/JJ0yRXtxY/LTCWAAA
+xJMVyrXAEUisrVAF/uiLbQAA
+34OrYUm6hkCjAfcxl5XmpgAA
+GRTp68U9ekK2ElWFr9WiQwAA
+
+
+akAggregate
+en8FxQY7BE+v9p/cI6Vh9wAA
+2bjs9/U4tkC8lb+E9SbivwAA
+4
+k0kci9s8c0267NURI9vZqAAA
+OBdTSTV+q02JS4nbKTN3zQAA
+ZFFrz9pNxkSyAH9Z/XksWgAA
+MrG1uu8oxkq+23hoqQu0xAAA
+
+
+
+platformUID
+AXaa4fXnMkSQbYhO++BySwAA
+4
+7IwNs/XM5kq9sOavQnifWwAA
+KF6DO0GUe0CRE/lr10Au4gAA
+3KpQaF4nJEGxjJRHvTrFEgAA
+a2ZZ7w/bh0SLYLZBDwm1xAAA
+1
+gl2nXNPFBUKFkpD9Y+jkywAA
+
+
+AXaa4fXnMkSQbYhO++BySwAA
+4
+tDLH1i4k3UO0L1TdSkKZYwAA
+AzklgW83WESiukDNEZieWgAA
+1ooS1thFeUmH+yywkTVgbwAA
++fIpxqYW/EONaV06QMwsxAAA
+2
+
+WUcaNoS+W0ScfGgjVLs+nAAA
+3n6KakpGs0aeHYe1gxZ0PwAA
+4
+MB5y7axnz0axYeNDfNaumAAA
+6QA1ZDq+C0W2UMGjsp0qogAA
+oImhcJZ/X064wgXtKgMGWgAA
+iqPBju4/tkSRJMOkIadgJAAA
+
+
+akAggregate
+WUcaNoS+W0ScfGgjVLs+nAAA
+2bjs9/U4tkC8lb+E9SbivwAA
+4
+E9dMmHeogUyoDU3wpcesqQAA
+ABkFdLXMnUGf6d52LhkgvwAA
+9C5/GVzHS0aMsZ1Y7GZRuwAA
+Ctauxi+dwkC6Tu25w0/4RQAA
+
+
+
+
+hcr
+8/PDgZYaSkyhn9djg2OS7wAA
+1
+
+hcr
+qbPN/Ar/t0KiMLxOhrAKUAAA
+
+pyIYOwYMDEeZrQT3ju6dFwAA
+
+
+
+
+implbase
+8/PDgZYaSkyhn9djg2OS7wAA
+6
+4mngVqbP4Ea7+EC/9bKjCgAA
+VWp/rJMg2kOLFXwFg0J96gAA
+jKpvSZoHtkq5hgIRvjK8eAAA
+nsTcPUP9yEKZ2Ue56O4iCAAA
+2WZs30HgKkeocNW87z6sVQAA
+ibZP/x+DQUur6Dm7HuS6kgAA
+1
+taqNNc4Me0uannQ7Vlc89gAA
+1
+LIobfyFbwUOnOz751BxBWAAA
+
+
+
+Implementation Model
+UMLStandard
+implementationModel
+7KBTiD3bXUedYhpH6MqM/gAA
+1
+
+Main
+ZZnOc1BB802VNyN7Blj6agAA
+
+dPrKTvLEr0CWArbuShV1qgAA
+
+
+
+
+Deployment Model
+UMLStandard
+deploymentModel
+7KBTiD3bXUedYhpH6MqM/gAA
+1
+
+Main
+B7rSNDDyBUqpmqGILzLvCgAA
+
+HsXxbkByQka1ntXTL8fe5wAA
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/ruleml-plugin/ruleml.jpg
Binary file configurationengine/doc/plugins/ruleml-plugin/ruleml.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/ruleml-plugin/ruleplugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/ruleml-plugin/ruleplugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,163 @@
+User guide for Rule Plugin usage in ConE
+----------------------------------------
+
+Introduction
+'''''''''''''
+This page describes how to use ConE Rule plugin. With rule plugin one may set rule configuration
+for the values in the confml. So for ex. one may have a case where is one confml value is been setted
+and one may create a rule configuration that if this value is for ex. 'foo' then some other value is
+'bar'. Value may be required or configures.
+
+
+Creating a rule configuration file
+''''''''''''''''''''''''''''''''''
+Create a new file a example.ruleml and set it's file encoding to UTF-8.
+Place the file in the impml folder in configuration project.
+The file is a XML base file.
+First set the encoding tag
+
+.. code-block:: xml
+
+ *
+
+and then create a root tag
+
+.. code-block:: xml
+
+ *
+
+give a set of rules for ex.
+
+.. code-block:: xml
+
+ mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True *
+
+and close the ruleml tag.
+
+One may say use several boolean operators for the configuration rule like for ex.
+
+.. code-block:: xml
+
+ and, or, ==, !=*
+
+Like for ex.
+
+.. code-block:: xml
+
+ mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True *
+
+means that if reference link mms/imagesize in some confml file is set to large then reference
+link pd/ref1 value is true and pd/ref2 value is set to true also.
+
+**All in all one may create a dependency like project configuration with ruleml files.**
+
+Ruleml version 2 adds support for calling `Python `_ expressions from rules. Python expression are defined between ``{%`` and ``%}``:
+
+.. code-block:: xml
+
+ feat1.setting2 == True configures feat2.setting2 = {% ${feat3.setting2} %}
+
+Expression return a result, that can be used in rule e.g. to set a value to some setting in configuration. These expression can be used to create more complex logic into rules that is not possible with standard rule expressions. Inside eval expressions features and feature's values can be accessed by following syntax:
+
+Accesses to the value::
+
+ ${Feature.Setting}
+
+Accesses to the feature object::
+
+ @{Feature.Setting}
+
+Python functions or constants that can be accessed inside expressions can be defined by ```` elements:
+
+.. code-block:: xml
+
+
+ def my_function1(attribute):
+ return attribute + 1
+
+
+ CONST_1 = "my constant"
+
+
+
+Definitions can be inside elements or definitions can be in separate file referenced with ``file`` attribute.
+The path specified in this attribute is relative to the RuleML implementation file. So, for example, if your implementation
+file's location is ``some/layer/implml/my_rules.ruleml``, the actual path specified in the above example would be
+``some/layer/implml/.scripts/evals_in_file.py``. It is recommended to place the scripts under a directory beginning
+with a dot, so that the plug-in loader does not attempt to load the .py file as an implementation (files and directories beginning
+with a dot are ignored in the implementation loading phase).
+
+Running
+'''''''''''''''''''''
+
+::
+
+ cone generate -p someproject.cpf -o c:/temp/coneoutput -i rulemlfile.ruleml
+
+Generates files out of configuration file and takes the implementation rulemlfile.ruleml in concern,
+and the output is to been set to -o given folder
+
+for more example see the cone documentation
+
+Examples
+'''''''''
+
+
+**Ruleml version 1 file example**
+
+.. code-block:: xml
+
+
+
+ imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget
+ mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True
+ mms.imagesize == 'small' configures pd.ref1 = False and pd.ref2 = True
+ mms.imagesize == 'extrasmall' configures pd.ref1 = False and pd.ref2 = False
+ mms.imagesize == 'extralarge' configures pd.ref1 = True and pd.ref2 = False
+
+
+**What do the example ruleml file means**
+
+The example file set the values upon the image size. First it sets the iMaker output
+location target and then it starts to set the mms message image size settings. So if for ex.
+*mms/imagesize* refence link value in confml file is set to *extralarge* then the value of
+*pd/ref1* is set to *true* and the value *pd/ref2* is set to false.
+
+
+**Ruleml version 2 file example**
+
+.. code-block:: xml
+
+
+
+ feat1.setting1 == 'somevalue' configures feat2.setting1 = {% len( ${feat3.setting1} ) %}
+ feat1.setting2 == True configures feat2.setting2 = {% my_function1( ${feat3.setting2} ) %}
+ feat1.setting3 == True configures feat2.setting3 = {% CONST_1 %}
+ {% my_function2( ${feat1.setting4} ) %} configures feat2.setting4 = False
+ {% @{feat1.setting5}.get_type() %} == 'int' configures feat2.setting5 = 'integer'
+ feat1.setting6 == True configures feat2.setting6 = {% '0x%08X' % ${feat2.setting6} %}
+
+ def my_function1(attribute):
+ return attribute + 1
+ def my_function2(attribute):
+ if attribute == 'abc':
+ return True
+ else:
+ return False
+
+
+ CONST_1 = "my constant"
+
+
+
+
+XSD
+'''''''''
+
+Ruleml version 1: :download:`ruleml.xsd `
+
+Ruleml version 2: :download:`ruleml2.xsd `
+
+FAQ
+'''''''''
+This will be updated based on the questions.
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/tag-fil.jpg
Binary file configurationengine/doc/plugins/tag-fil.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/templateml-plugin/templateml.jpg
Binary file configurationengine/doc/plugins/templateml-plugin/templateml.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/templateml-plugin/templateml_example0.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/templateml-plugin/templateml_example0.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+ Description field text
+
+
+
+
+
+ This template uses custom filter to count the sum of 2 and 3:
+ 2+3={{ 2|example_filter(3) }}
+
+
+ lambda a,b: a+b
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/templateml-plugin/templateml_example1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/templateml-plugin/templateml_example1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+{% for feature in feat_list %}
+{{ feature._fqr }}: {{ feature._value }}
+{% endfor %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/templateml-plugin/templateml_example1_result.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/templateml-plugin/templateml_example1_result.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+Feature1.FolderSetting: default_folder
+
+Feature1.RealSetting: 3.14
+
+Feature2.FileSetting: default_file.txt
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/templateml-plugin/templateml_example2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/templateml-plugin/templateml_example2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+{% if feat_tree.Feature1.StringSetting1 %}
+ feat_tree.Feature1.StringSetting1._value
+{% elif feat_tree.Feature1.StringSetting2 %}
+ feat_tree.Feature1.StringSetting2._value
+{% else %}
+ my default setting
+{% endif %}
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/templateml-plugin/templatemlplugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/templateml-plugin/templatemlplugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,220 @@
+User guide for Template Configuration File Markup Language (TemplateML) Plugin
+------------------------------------------------------------------------------
+
+Introduction
+'''''''''''''
+This page describes how to use and configure Template Configuration File Markup Language
+(TemplateML) plugin fo ConE. TemplateML is one of the implementation mapping languages for
+Configuration Markup Language (ConfML). This plugin is used to generate arbitrary text file
+formats. It doesn't have a specific extension or encoding. Currently
+this language uses `Jinja 2 template engine `_ to generate
+output files.
+
+Templates are based on Jinja syntax and semantics that are described in detail `Jinja 2 Template Designer Documentation `_
+One important concept in Jinja is `template inheritance `_, which means that you can overwrite only specific blocks within a template, customizing it while also keeping the changes at a minimum.
+
+Templateml plugin supports also `XML Inclusions (XInclude) `_
+that allows a mechanism for merging XML documents. By writing inclusion tags in a "main"
+document it automatically includes other documents.
+
+TemplateML files are executed by default in **normal** :ref:`invocation phase `.
+
+Template Configuration File ML
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The TemplateML syntax is a extension of Configuration markup language (confml). The term in confml for this extension
+is implementation method language (implml), which in TemplateML case is a xml file.
+
+All input values, excluding template and filter elements text content, can be given as ConfML refs.
+
+ * Namespace: ``http://www.s60.com/xml/templateml/1``
+ * File extension: ``templateml``
+
+.. note::
+
+ More information about :ref:`file extensions `.
+
+TemplateML Elements
+...................
+
+The TemplateML model is drawn out as a uml model in below picture.
+
+ .. image:: templateml.jpg
+
+.. note::
+
+ TemplateML supports also common ImplML elements. More information about :ref:`ImplML elements `.
+
+
+templateml element
+**************************
+
+The root element of the templateml file is always templateml, which defines the xml namespace (xmlns)
+to http://www.s60.com/xml/templateml/1 in the current version.
+
+**templateml example**:
+
+.. code-block:: xml
+
+
+
+desc element
+**************************
+
+Description element's content is not used in output file generation, but it can be used to describe temlplateml file.
+
+**desc example**:
+
+.. code-block:: xml
+
+ Description field text
+
+output element
+**************************
+
+Output element describes how one output file is generated. Output has one mandatory attribute 'file' that defines filename for output file. If you want to generate output file to some other than default folder, it can be done by defining a output directory to 'dir' attribute. Default encoding for output file is 'UTF-8', if some other encoding is wanted, it can be defined by 'encoding' attribute. This encoding should be one of the standard Python codecs encoding (see http://docs.python.org/library/codecs.html#standard-encodings).
+
+Template element is mandatory child element for output element. One output element can have only one template element.
+Output element can also contain optional filter elements that are specific just for this output file. Global filters that are common for all output files should be defined under root templateml element.
+
+**output example**:
+
+.. code-block:: xml
+
+
+ Hello world!
+ lambda a,b: a+b
+ lambda a,b: a*b
+
+
+For unicode transformation formats, control over the BOM is provided by the attribute ``bom``.
+This attribute defines whether the BOM is written to the output or not. If the attribute is not
+defined, the default behavior of the encoding is used (i.e. BOM is written for UTF-16, but not for UTF-16-BE,
+UTF-16-BE or UTF-8). For encodings where the BOM makes no sense (e.g. ASCII), the attribute does nothing.
+
+**Examples**:
+
+.. code-block:: xml
+
+
+ test
+
+
+
+ test
+
+
+template element
+****************
+
+Template can be defined in template element or in external file. If both are defined file attribute overwrites.
+
+**template example 1:**:
+
+.. code-block:: xml
+
+ Some Jinja template goes here
+
+Notice that if you want to define create xml output files and you don't want to encode special characters you can use CDATA section http://www.w3schools.com/xmL/xml_cdata.asp.
+
+.. code-block:: xml
+
+
+ Some Jinja xml template
+ ]]>
+
+
+**template example 2:**:
+
+.. code-block:: xml
+
+
+
+
+With template's file attribute template is defined relatively to templateml file.
+
+filter element
+**************************
+
+With filter element you can define custom filters. Custom filters are just regular Python functions that take the left side of the filter as first argument and the the arguments passed to the filter as extra arguments or keyword arguments. Filter element has mandatory 'name' attribute that defines the name of the filter. Name is used in template to refer to that filter. Filter can be defined in filter element or in external file. If both are defined file attribute overwrites.
+
+`Jinja has built-in filters `_ (e.g. capitalize, replace, trim, urlize, format, escape) that can be utilized without any extra definitions templateml file.
+
+**filter example**:
+
+.. code-block:: xml
+
+ lambda a,b: a-b
+
+With filter's file attribute filter is defined relatively to templateml file.
+
+Variables
++++++++++
+
+The TemplateML plugin passes variables to the templates you can mess around in the template. Every feature has
+following attributes:
+
+ * _name
+ * _namespace
+ * _value
+ * _fqr
+ * _type
+
+Currently TempleML plugin passes features in three different structure: feat_tree, feat_list and configuration.
+
+feat_tree
++++++++++
+
+Variable 'feat_tree' contains features in a tree structure. It allows easy access to features attributes,
+when feature explicitly known:
+
+.. literalinclude:: templateml_example2.txt
+ :language: xml
+
+feat_list
+++++++++++++++++++++++++++
+
+Variable 'feat_tree' contains features in an array and allows easy access to all features e.g. in loops:
+
+.. literalinclude:: templateml_example1.txt
+ :language: xml
+
+Generates to output file e.g following content:
+
+.. literalinclude:: templateml_example1_result.txt
+ :language: xml
+
+configuration
+++++++++++++++++++++++
+
+Configuration object that is defined ConE API can be accessed also inside template.
+
+.. code-block:: xml
+
+ Configuration name: {{ configuration.get_path() }}
+ {% for feature in configuration.get_default_view().get_features('**') %}
+ {{ feature.fqr }}
+ {% endfor %}
+
+
+
+Examples
+'''''''''
+
+An example of templateml file, that generates two output files, utilizes XInclude and defines two custom filters:
+
+.. literalinclude:: templateml_example0.txt
+ :language: xml
+
+XSD
+'''
+
+Download: :download:`templateml.xsd `
+
+
+FAQ
+'''''''''
+This will be updated based on the questions.
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/thememl-plugin/theme.thememl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/thememl-plugin/theme.thememl Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+
+
+ C:\Program Files\Nokia\Carbide.ui Theme Edition 3.4
+ CVC_PreinstalledContent/CVC_PreInstalledThemesFolder
+
+ CVC_Theme_ref/CVC_DefaultTheme_ref
+ KCRUidPersonalisation/KPslnActiveSkinUid
+ KCRUidPersonalisation/KPslnActiveSkinUid1
+
+
+ CVC_Theme_ref/CVC_DefaultThemeMode2_ref
+ KCRUidPersonalisation/KPslnActiveSkinUid2
+ KCRUidPersonalisation/KPslnActiveSkinUid3
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/thememl-plugin/themelplugin.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/thememl-plugin/themelplugin.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,99 @@
+User guide for Theme Plugin usage in ConE
+-----------------------------------------
+
+Introduction
+'''''''''''''
+This page describes how to use ConE Theme plugin. Theme plugin extracts the theme content from the
+.cpf file. It needs a .thememl file in the implml folder
+
+
+The thememl syntax is a extension of Configuration markup language (confml). The term in confml for this extension
+is implementation method language (implml), which in thememl case is a xml file.
+
+
+Theme elements
+''''''''''''''
+
+The root element of the theme file is always thememl, which defines the xml namespace (xmlns)
+to http://www.s60.com/xml/thememl/1 in the current version.
+
+Theme example
+^^^^^^^^^^^^^
+.. literalinclude:: theme.thememl
+ :language: xml
+
+
+
+
+carbideuiPath
+^^^^^^^^^^^^^^
+
+To create a the Theme plugin uses makepackage.bat file which is under the forder described in
+carbideuiPath tag. If none is setted the default is then C:\Program Files\Nokia\Carbide.ui Theme Edition 3.4
+
+
+
+themeDir
+^^^^^^^^
+Theme plugin available themes from this directory setted as confml ref
+
+
+activeTheme
+^^^^^^^^^^^
+
+One may describe a theme in this tag. You may have them as many as you want.
+It may hold one refSetting tag and several platformUID tags
+
+**activeTheme attributes**
+
+Each flag attribute can have unique hexa values.
+
+ * uid
+
+
+refSetting
+^^^^^^^^^^
+A ref confml setting key that describes the name of the .tpf file. Tpf file must always locate in the
+content folder
+
+
+platformUID
+^^^^^^^^^^^
+Is a ref in conml it may contain some value, but it will be replaced in the theme plugin to value
+given by the .pkg file and setted back to configuration. You may have more than one of these
+
+
+Note
+^^^^^
+The current implementation of the theme plugin relays the the .tpf file contain a .project file and
+it contains themepackage.pkg file
+
+
+XSD
+'''
+
+Download: :download:`thememl.xsd `
+
+
+FAQ
+'''
+
+Makepackage error
+'''''''''''''''''
+
+This problem is related to installation on Carbide.ui you can get it form
+here http://www.forum.nokia.com/info/sw.nokia.com/id/bb173537-4e67-496f-9967-50917d5cfc47/S60_Theme_Studio_for_Symbian_OS.html
+Install it. Goes by default to C:\Program Files\Nokia\Carbide.ui Theme Edition 3.4, but if you install it
+to a different location then you need to set right path to carbideuiPath tag. Chek that your system supports java
+programmin language. OPen command line editor and type java -version should be 1.5 or above
+
+My theme is not created to image
+''''''''''''''''''''''''''''''''
+
+Change the .tpf file extension to zip and extract it to some folder.
+View the contents, there should be .project file and themepackage.pkg file, if not
+then ConE cannot create you a theme to an image.
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/plugins/thememl-plugin/thememl.jpg
Binary file configurationengine/doc/plugins/thememl-plugin/thememl.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/rule.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/rule.rst Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,76 @@
+Rule
+====
+
+ A Configuration can contain rule's, which can be aplied to the :class:`~cone.public.api.Configuration`
+ :class:`~cone.public.api.Feature`'s. In ConE a single rule will create an instance of :class:`~cone.public.plugin.Relation`.
+
+ The textual format of a rules is always of form:
+ ::
+
+ relation_name .
+
+The rule dialect
+----------------
+
+ The features are accessed in the left and right side of the rule with the default :class:`~cone.public.api.View` of the :class:`~cone.public.api.Configuration`.
+ Basically ConE will get the default_view and use the :class:`~cone.public.api.ObjectContainer` member access to retrieve the feature.
+ There are few special characters that are converted to function calls in the rule transformation.
+
+ * ``*`` => refers to all immediate childer of this node, which is transformed to method call :meth:`cone.public.api.ObjectContainer.__objects__`
+ * ``**`` => refers to all childer of this node, which is transformed to method call :meth:`cone.public.api.ObjectContainer.__traverse__`
+
+ Both sides of the rule are something that the :class:`~cone.public.plugin.Relation` will somehow evaluate. How the left
+ side and right side are evaluated, is basically specific to the implementation of the :meth:`~cone.public.plugin.Relation.execute`
+ method of the :class:`~cone.public.plugin.Relation`. However certain basic evaluation rules apply to all :class:`~cone.public.plugin.Relation` objects.
+
+ When a feature is referred, ConE will try to return the value of the feature.
+ Then the Relation tries to evaluate if the given feature is bound and evaluates as True.
+
+ So for example referring to a feature.
+
+ ``group.fea1`` is the same as writing ``group.fea1==True`` for a boolean feature.
+ ``group.intfea1`` is the same as writing ``group.fea1!=0`` for a integer feature.
+
+ If a feature is unbound, trying to access its value will raise UnboundError.
+
+Boolean logic in rules
+----------------------
+
+ Both left and right side of the rule can contain normal boolean algebra that is utilized in the evaluation. This uses
+ default python syntax for boolean logic, with keywords *and*, *or*, *not*.
+
+Example of boolean logic
+^^^^^^^^^^^^^^^^^^^^^^^^
+::
+ a.b and c.d=10 depends (not a.b.x=10 or a.b.x=0)
+
+
+
+
+Rules with different multiplicity
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ The above mechanism enables that the rules can define relations with different multiplicity.
+
+ * one-to-one
+
+ * e.g. A depends B
+
+ * one-to-many
+
+ * e.g. A depends B.*, which is basically the same as wrinting A depends (B.child1 and B.child2 and ..)
+ * e.g. A depends B and C
+
+ * many-to-one
+
+ * e.g. A.* depends B
+
+ * many-to-many
+
+ * e.g. A.* depends B.*
+
+Examples
+--------
+
+ * A.B.C requires A.B.D
+ * fea.group.* requires fea.group
+ * wlan.setting maps voip.setting=10
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/XInclude.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/XInclude.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/XMLSchema.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/XMLSchema.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2358 @@
+
+
+
+
+
+ Part 1 version: Id: structures.xsd,v 1.2 2004/01/15 11:34:25 ht Exp
+ Part 2 version: Id: datatypes.xsd,v 1.3 2004/01/23 18:11:13 ht Exp
+
+
+
+
+
+ The schema corresponding to this document is normative,
+ with respect to the syntactic constraints it expresses in the
+ XML Schema language. The documentation (within <documentation> elements)
+ below, is not normative, but rather highlights important aspects of
+ the W3C Recommendation of which this is a part
+
+
+
+
+ The simpleType element and all of its members are defined
+ towards the end of this schema document
+
+
+
+
+
+ Get access to the xml: attribute groups for xml:lang
+ as declared on 'schema' and 'documentation' below
+
+
+
+
+
+
+
+ This type is extended by almost all schema types
+ to allow attributes from other namespaces to be
+ added to user schemas.
+
+
+
+
+
+
+
+
+
+
+
+
+ This type is extended by all types which allow annotation
+ other than <schema> itself
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This group is for the
+ elements which occur freely at the top level of schemas.
+ All of their types are based on the "annotated" type by extension.
+
+
+
+
+
+
+
+
+
+
+
+
+ This group is for the
+ elements which can self-redefine (see <redefine> below).
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ #all or (possibly empty) subset of {extension, restriction}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ #all or (possibly empty) subset of {extension, restriction, list, union}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ for maxOccurs
+
+
+
+
+
+
+
+
+
+
+
+ for all particles
+
+
+
+
+
+
+ for element, group and attributeGroup,
+ which both define and reference
+
+
+
+
+
+
+
+ 'complexType' uses this
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This branch is short for
+ <complexContent>
+ <restriction base="xs:anyType">
+ ...
+ </restriction>
+ </complexContent>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Will be restricted to required or forbidden
+
+
+
+
+
+ Not allowed if simpleContent child is chosen.
+ May be overriden by setting on complexContent child.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This choice is added simply to
+ make this a valid restriction per the REC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Overrides any setting on complexType parent.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This choice is added simply to
+ make this a valid restriction per the REC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No typeDefParticle group reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ #all or (possibly empty) subset of {substitution, extension,
+ restriction}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The element element can be used either
+ at the top level to define an element-type binding globally,
+ or within a content model to either reference a globally-defined
+ element or type or declare an element-type binding locally.
+ The ref form is not allowed at the top level.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ group type for explicit groups, named top-level groups and
+ group references
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ group type for the three kinds of group
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This choice with min/max is here to
+ avoid a pblm with the Elt:All/Choice/Seq
+ Particle derivation constraint
+
+
+
+
+
+
+
+
+
+ restricted max/min
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Only elements allowed inside
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ simple type for the value of the 'namespace' attr of
+ 'any' and 'anyAttribute'
+
+
+
+ Value is
+ ##any - - any non-conflicting WFXML/attribute at all
+
+ ##other - - any non-conflicting WFXML/attribute from
+ namespace other than targetNS
+
+ ##local - - any unqualified non-conflicting WFXML/attribute
+
+ one or - - any non-conflicting WFXML/attribute from
+ more URI the listed namespaces
+ references
+ (space separated)
+
+ ##targetNamespace or ##local may appear in the above list, to
+ refer to the targetNamespace of the enclosing
+ schema or an absent targetNamespace respectively
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A subset of XPath expressions for use
+in selectors
+ A utility type, not for public
+use
+
+
+
+ The following pattern is intended to allow XPath
+ expressions per the following EBNF:
+ Selector ::= Path ( '|' Path )*
+ Path ::= ('.//')? Step ( '/' Step )*
+ Step ::= '.' | NameTest
+ NameTest ::= QName | '*' | NCName ':' '*'
+ child:: is also allowed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A subset of XPath expressions for use
+in fields
+ A utility type, not for public
+use
+
+
+
+ The following pattern is intended to allow XPath
+ expressions per the same EBNF as for selector,
+ with the following change:
+ Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The three kinds of identity constraints, all with
+ type of or derived from 'keybase'.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+ A public identifier, per ISO 8879
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ notations for use within XML Schema schemas
+
+
+
+
+
+
+
+
+ Not the real urType, but as close an approximation as we can
+ get in the XML representation
+
+
+
+
+
+
+
+
+
+ First the built-in primitive datatypes. These definitions are for
+ information only, the real built-in definitions are magic.
+
+
+
+ For each built-in datatype in this schema (both primitive and
+ derived) can be uniquely addressed via a URI constructed
+ as follows:
+ 1) the base URI is the URI of the XML Schema namespace
+ 2) the fragment identifier is the name of the datatype
+
+ For example, to address the int datatype, the URI is:
+
+ http://www.w3.org/2001/XMLSchema#int
+
+ Additionally, each facet definition element can be uniquely
+ addressed via a URI constructed as follows:
+ 1) the base URI is the URI of the XML Schema namespace
+ 2) the fragment identifier is the name of the facet
+
+ For example, to address the maxInclusive facet, the URI is:
+
+ http://www.w3.org/2001/XMLSchema#maxInclusive
+
+ Additionally, each facet usage in a built-in datatype definition
+ can be uniquely addressed via a URI constructed as follows:
+ 1) the base URI is the URI of the XML Schema namespace
+ 2) the fragment identifier is the name of the datatype, followed
+ by a period (".") followed by the name of the facet
+
+ For example, to address the usage of the maxInclusive facet in
+ the definition of int, the URI is:
+
+ http://www.w3.org/2001/XMLSchema#int.maxInclusive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NOTATION cannot be used directly in a schema; rather a type
+ must be derived from it by specifying at least one enumeration
+ facet whose value is the name of a NOTATION declared in the
+ schema.
+
+
+
+
+
+
+
+
+
+ Now the derived primitive types
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern specifies the content of section 2.12 of XML 1.0e2
+ and RFC 3066 (Revised version of RFC 1766).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern matches production 7 from the XML spec
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern matches production 5 from the XML spec
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pattern matches production 4 from the Namespaces in XML spec
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #all or (possibly empty) subset of {restriction, union, list}
+
+
+ A utility type, not for public use
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Can be restricted to required or forbidden
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Required at the top level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Forbidden when nested
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ We should use a substitution group for facets, but
+ that's ruled out because it would allow users to
+ add their own, which we're not ready for yet.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ base attribute and simpleType child are mutually
+ exclusive, but one or other is required
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ itemType attribute and simpleType child are mutually
+ exclusive, but one or other is required
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ memberTypes attribute must be non-empty or there must be
+ at least one simpleType child
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/confml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/confml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/confml2.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/confml2.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/contentml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/contentml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/contentml2.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/contentml2.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/crml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/crml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/gcfml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/gcfml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/hcrml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/hcrml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/ibyml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/ibyml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/imageml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/imageml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/projectml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/projectml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/ruleml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/ruleml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/ruleml2.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/ruleml2.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/templateml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/templateml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/thememl.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/thememl.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/xlink.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/xlink.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,129 @@
+
+
+
+
+
+ Note this schema is NOT a normative schema - - It contains
+ attribute types derived from all the attribute definitions found in
+ the XLink Recommendation available at
+ http://www.w3.org/TR/2001/REC-xlink-20010627 Section 4.1
+ (http://www.w3.org/TR/2001/REC-xlink-20010627/#N1238) provides a
+ summary of the element types on which the global attributes are
+ allowed, with an indication of whether a value is required or
+ optional.
+
+
+
+ The XLink Element Type Attribute. Note: xml:lang is not
+ required if the value of the type attribute is "title", but provides
+ much of the motivation for title elements in addition to attributes.
+ A W3C XML Schema definition of the xml:lang attribute can be found
+ at: http://www.w3.org/2001/xml.xsd
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The Locator Attribute.
+
+
+
+
+ The Arcrole Semantic Attribute.
+
+
+
+
+ The Role Semantic Attribute.
+
+
+
+
+ The Title Semantic Attribute.
+
+
+
+
+ The Show Behavior Attribute.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The Actuate Behavior Attribute.
+
+
+
+
+
+
+
+
+
+
+
+
+ The Label Traversal Attribute.
+
+
+
+
+ The From Traversal Attribute.
+
+
+
+
+ The To Traversal Attribute.
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/doc/xsd/xml.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/xsd/xml.xsd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,145 @@
+
+
+
+
+
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ id (as an attribute name): denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+
+
+
+
+ This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+ attributes on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ <schema . . .>
+ . . .
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ <type . . .>
+ . . .
+ <attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes
+
+
+
+ In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2007/08/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself, or with the XML namespace itself. In other words, if the XML
+ Schema or XML namespaces change, the version of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2007/08/xml.xsd will not change.
+
+
+
+
+
+ Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility. See
+ RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+ at http://www.iana.org/assignments/lang-tag-apps.htm for
+ further information.
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.
+
+
+
+
+
+ See http://www.w3.org/TR/xml-id/ for
+ information about this attribute.
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/export_bat.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/export_bat.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+@echo off
+
+call ant export-bat -Dbuild.bat_export_path=%1 -Dbuild.plugin_package="%2"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/generatedoc-build.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/generatedoc-build.xml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/install.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/install.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+@echo off
+
+call ant install -Dbuild.cone_install_path=%1 -Dbuild.plugin_package="%2"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/linux.properties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/linux.properties Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+os.linux.userbin = /home/hudson/bin
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/pack.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/pack.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+@echo off
+
+call ant pack -Dbuild.cone_pack_path=%1 -Dbuild.plugin_package="%2"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/pack_bat.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/pack_bat.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+@echo off
+
+call ant pack-bat -Dbuild.bat_pack_path=%1 -Dbuild.plugin_package="%2"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/pack_dualversion.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/pack_dualversion.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+@echo off
+
+call ant pack-dualversion -Dbuild.cone_pack_path=%1 -Dbuild.dualversioninstall.path1=%2 -Dbuild.dualversioninstall.path2=%3 -Dbuild.plugin_package="%4"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/run_bat.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/run_bat.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+@echo off
+
+call ant run-bat -Dbuild.base_path=%1 -Dbuild.plugin_package="%2"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,85 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+
+:: ============================================================================
+:: Name : cone.cmd
+:: Part of : ConE
+:: Description : ConE tool wrapper for Windows
+:: Version : %version: 1 %
+::
+:: ============================================================================
+
+
+
+@echo off
+setlocal
+
+set CONE_CMDARG=%*
+set CONE_BASEDIR=%~dp0
+set PYTHONCASEOK=1
+
+@rem Check that Python is available
+call python -h >nul 2>&1
+if %errorlevel% neq 0 (
+echo Python is required to run ConE!
+exit /b 1
+)
+
+@REM Find out Python version
+set VERFILE=%TEMP%\cone_version_check.tmp
+python -c "import sys; print sys.version[:3]" > %VERFILE%
+set varNUM=0
+for /f "tokens=*" %%T in (%VERFILE%) do call :varSET %%T
+if exist %VERFILE% del %VERFILE%
+
+
+@REM Set the used base directory based on the version
+if %VER1%==2.5 (
+set CONE_BASEDIR=%CONE_BASEDIR%cone\2.5\
+goto EndVersionCheck
+)
+if %VER1%==2.6 (
+set CONE_BASEDIR=%CONE_BASEDIR%cone\2.6\
+goto EndVersionCheck
+)
+echo You are using an unsupported Python version (%VER1%)
+echo ConE requires Python 2.5 or 2.6
+exit /b 1
+)
+:EndVersionCheck
+
+@rem Check that this ConE installation supports the Python version
+if not exist "%CONE_BASEDIR%" (
+echo Python version %VER1% is not supported by this ConE installation
+exit /b 1
+)
+
+
+@rem Set environment variables and run cone_tool.py
+set CONE_LIBDIR=%CONE_BASEDIR%\lib
+set CONE_SCRIPTDIR=%CONE_BASEDIR%\scripts
+set PATH=%CONE_SCRIPTDIR%;%PATH%
+set PYTHONPATH=%CONE_LIBDIR%;%PYTHONPATH%
+call python "%CONE_SCRIPTDIR%\cone_tool.py" %CONE_CMDARG%
+exit /b %ERRORLEVEL%
+
+endlocal
+
+:VarSET
+set /a varNUM=%varNUM%+1
+set VER%varNUM%=%1
+
+:: END OF cone.cmd
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone.prj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone.prj Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,44 @@
+[Project ID]
+Signature=UE Proj: v.1
+[Project Information]
+Create Tagfile=0
+Filter=
+Include Sub Directories=1
+Project Start=D8070B0001000A000C001B00320000004E
+Project Tagfile=
+Project Wordfile=
+Relative to Project File=1
+Use Relative Directory=1
+Working Time=427910
+[Files]
+0=C:\Users\svn\isource\cone\trunk\source\
+[Group Filter]
+.\abstract\=*.py
+.\cone\=*.py
+.\storage\=*.py
+C:\Users\svn\isource\cone\trunk\source\=*.py
+C:\Users\svn\isource\newcone\source\=*.py
+[Folders]
+.\cone\ - tests=1
+C:\Users\svn\isource\cone\trunk\source\=1
+C:\Users\svn\isource\cone\trunk\source\ - cone=1
+C:\Users\svn\isource\cone\trunk\source\ - cone - core=1
+C:\Users\svn\isource\cone\trunk\source\ - cone - storage=1
+C:\Users\svn\isource\cone\trunk\source\ - storage=1
+C:\Users\svn\isource\cone\trunk\source\ - storage - tests=1
+C:\Users\svn\isource\newcone\source\=1
+C:\Users\svn\isource\newcone\source\ - cone=1
+C:\Users\svn\isource\newcone\source\ - cone - storage - tests=1
+C:\Users\svn\isource\cone\trunk\source\ - cone - confml=1
+C:\Users\svn\isource\cone\trunk\source\ - cone - storage - tests=1
+C:\Users\svn\isource\cone\trunk\source\ - cone - confml - tests=1
+C:\Users\svn\isource\cone\trunk\source\ - cone - core - tests=1
+C:\Users\svn\isource\cone\trunk\source\ - cone - tests=1
+[Open Files]
+Active File Display Mode=3
+Active File Index=0
+Open File Line0=0
+Open File Pos0=0
+Open File Window Pos0=2,3,-1,-1,-4,-23,22,22,948,436
+Open File0=C:\USERS\svn\isource\cone\trunk\source\set_env_to_test.cmd
+Open File1=
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone.sh Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,83 @@
+#!/bin/bash
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# ConE tool wrapper for Unix
+
+# Check that Python is available
+# ------------------------------
+python --version &> /dev/null
+if [ $? -ne 0 ]
+then
+ echo "Python is required to run ConE!"
+ exit 1
+fi
+
+
+# Determine the path where ConE is installed
+# ------------------------------------------
+
+# Try to derefence a symlink
+SCRIPT_FILE=`readlink $0`
+if [ "$SCRIPT_FILE" = "" ]
+then
+ # Not a symlink, the first command line parameter can be used
+ SCRIPT_FILE=$0
+fi
+CONE_BASEDIR=`dirname "$SCRIPT_FILE"`/cone
+
+
+# Find out the Python version
+# ---------------------------
+PYTHON_VERSION=`python -c "import sys; print sys.version[:3]"`
+#echo "Python version: $PYTHON_VERSION"
+
+
+# Set the correct lib and scripts directories
+# to use based on the Python version
+# -------------------------------------------
+case $PYTHON_VERSION in
+"2.5")
+ CONE_BASEDIR="$CONE_BASEDIR/2.5"
+ ;;
+"2.6")
+ CONE_BASEDIR="$CONE_BASEDIR/2.6"
+ ;;
+*)
+ echo "You are using an unsupported Python version ($PYTHON_VERSION)"
+ echo "ConE requires Python 2.5 or 2.6"
+ exit 1
+ ;;
+esac
+
+#echo "CONE_BASEDIR: $CONE_BASEDIR"
+
+
+# Check that this ConE installation supports the Python version
+# -------------------------------------------------------------
+if [ ! -e "$CONE_BASEDIR" ]
+then
+ echo "Python version $PYTHON_VERSION is not supported by this ConE installation"
+ exit 1
+fi
+
+
+# Override PYTHONPATH so that the libraries in
+# the standalone installation are used
+# --------------------------------------------
+export PYTHONPATH="$CONE_BASEDIR/lib:$PYTHONPATH"
+
+# Run cone_tool.py
+# ----------------
+python $CONE_BASEDIR/scripts/cone_tool.py $@
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = "1.1.5"
+_svnrevision = ""
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/all.doxygen
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/all.doxygen Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1294 @@
+# Doxyfile 1.5.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that
+# follow. The default is UTF-8 which is also the encoding used for all text before
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
+# possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = cone
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doxygen_output
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = YES
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be extracted
+# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
+# where file will be replaced with the base name of the file that contains the anonymous
+# namespace. By default anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command , where is the value of
+# the FILE_VERSION_FILTER tag, and is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# This tag can be used to specify the character encoding of the source files that
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS = *.py
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = *.pyc
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the output.
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command , where
+# is the value of the INPUT_FILTER tag, and is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
+# then you must also enable this option. If you don't then doxygen will produce
+# a warning and turn it on anyway
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
+# be found in the default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a caller dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the number
+# of direct children of the root node in a graph is already larger than
+# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+import os
+import sys
+
+__all__ = ["model"]
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/mapping.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/mapping.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,87 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+
+"""
+Methods for Mapping Carbon model to other data model objects
+"""
+from cone.public import api, exceptions, container, utils
+from cone.public.mapping import BaseMapper
+from cone.carbon import model
+
+""" Carbon to confml model mapping is done in Carbon2confml """
+from cone.confml import model as confmlmodel
+
+class Carbon2confml(object):
+ """
+ Carbon2confml class maps Carbon model object to confml model objects.
+ """
+ def __init__(self):
+ self.MAPPING_TABLE = {model.CarbonConfiguration : self.configuration,
+ model.FeatureList : self.configuration,
+ model.CarbonFeature: self.setting,
+ model.CarbonSetting: self.setting,
+ model.CarbonIntSetting: self.setting,
+ model.CarbonBooleanSetting: self.setting,
+ model.CarbonStringSetting: self.setting,
+ model.CarbonSelectionSetting: self.setting}
+ pass
+
+ def map_object(self, object):
+ """
+ Return a confml model object from Carbon object
+ """
+ try:
+ return self.MAPPING_TABLE[object.__class__](object)
+ except KeyError:
+ return object
+
+ def configuration(self, object):
+ """
+ Map a CarbonConfiguration object to a ConfmlConfiguration
+ """
+ mapdict = object._dict()
+ mapobj = confmlmodel.ConfmlConfiguration(**mapdict)
+ return mapobj
+
+ def setting(self, object):
+ """
+ Map a CarbonSetting object to a ConfmlSetting
+ """
+ mapdict = object._dict()
+ if object.__class__ == model.CarbonFeature:
+ mapobj = api.Feature(**mapdict)
+ elif object.__class__ == model.CarbonIntSetting:
+ mapobj = confmlmodel.ConfmlIntSetting(**mapdict)
+ elif object.__class__ == model.CarbonBooleanSetting:
+ mapobj = confmlmodel.ConfmlBooleanSetting(**mapdict)
+ elif object.__class__ == model.CarbonSelectionSetting:
+ mapobj = confmlmodel.ConfmlSelectionSetting(**mapdict)
+ elif object.__class__ == model.CarbonStringSetting:
+ mapobj = confmlmodel.ConfmlSetting(**mapdict)
+ elif object.__class__ == model.CarbonSetting:
+ mapobj = confmlmodel.ConfmlSetting(**mapdict)
+ else:
+ raise exceptions.IncorrectClassError('Cannot find a mapping object for this class %s!' % object.__class__)
+ return mapobj
+
+MAPPERS = \
+{ 'confml' : Carbon2confml,
+ 'carbon' : BaseMapper
+}
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/model.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/model.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,182 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+
+import posixpath
+import datetime
+
+
+"""
+Base class for Carbon specific elements.
+Attributes:
+"""
+from cone.public import api, exceptions, container, utils
+from cone.confml import model as confmlmodel
+
+class ResourceList(object):
+ def __init__(self):
+ self.resources = {}
+
+ def add_resource(self,resource):
+ self.resources[resource.get_path()] = resource
+
+ def get_resource(self,path):
+ return self.resources[path]
+
+ def remove_resource(self,path):
+ del self.resources[path]
+
+ def list_resources(self):
+ return self.resources.keys()
+
+ def __len__(self):
+ return len(self.resources)
+
+ def __getitem__(self, key):
+ return self.resources[key]
+
+ def __setitem__(self, key, value):
+ self.resources[key] = value
+
+ def __delitem__( self, key):
+ del self.resources[key]
+
+ def __iter__(self):
+ return iter(self.resources.values())
+
+
+class ConfigurationResource(object):
+ FILE_EXTENSION = '/root.confml'
+ def __init__(self, **kwargs):
+ self.name = kwargs.get('configuration_name', None)
+ self.path = kwargs.get('path', None)
+ self.parent_config = kwargs.get('parent_config', None)
+ self.version = kwargs.get('version_identifier', None)
+
+ def get_path(self):
+ path = utils.resourceref.remove_begin_slash(self.path)
+ path = utils.resourceref.remove_end_slash(path)
+ return path + self.FILE_EXTENSION
+
+ def __str__(self):
+ return "%s = %s : %s:%s" % (self.get_path(),self.path,self.name, self.version)
+
+class FeatureListResource(object):
+ CONFML_EXTENSION = '.confml'
+ CARBON_EXTENSION = '.featurelist'
+ def __init__(self, **kwargs):
+ self.path = kwargs.get('path', None)
+ self.version_title = kwargs.get('version_title', None)
+ self.type = kwargs.get('type', None)
+ self.list_id = kwargs.get('list_id', None)
+ self.expanded = kwargs.get('expanded', None)
+ self.list_version_id = kwargs.get('list_version_id', None)
+ self.version_identifier = kwargs.get('version_identifier', None)
+ self.is_latest_version = kwargs.get('is_latest_version', None)
+ self.can_be_released = kwargs.get('can_be_released', None)
+ self.has_external_relations = kwargs.get('has_external_relations', None)
+
+ def get_path(self):
+ path = utils.resourceref.remove_begin_slash(self.version_title)
+ path = utils.resourceref.remove_end_slash(path)
+ return path + self.CONFML_EXTENSION
+
+ def get_carbon_path(self):
+ path = utils.resourceref.remove_begin_slash(self.version_title)
+ path = utils.resourceref.remove_end_slash(path)
+ return path + self.CARBON_EXTENSION
+
+ def __str__(self):
+ return "%s = %s : %s" % (self.get_path(),self.path,self.version_title)
+
+class CarbonElement(object):
+ pass
+
+ def _get_mapper(self,modelname):
+ """
+ Return a instance of appropriate mapper for given model.
+ """
+ mapmodule = __import__('cone.carbon.mapping')
+ return mapmodule.carbon.mapping.MAPPERS[modelname]()
+
+
+class CarbonConfiguration(CarbonElement, confmlmodel.ConfmlConfiguration):
+ def __init__(self, ref='', **kwargs):
+ super(CarbonConfiguration, self).__init__(ref, **kwargs)
+ if self.meta == None:
+ self.meta = {}
+
+ self.name = kwargs.get('name') or utils.resourceref.remove_ext(utils.resourceref.psplit_ref(self.path)[-1])
+ self.meta.add('type',kwargs.get('type', 'configurationroot'))
+ self._version_identifier = kwargs.get('version_identifier', None)
+
+ @property
+ def version_identifier(self):
+ if self._version_identifier == None:
+ dt = datetime.datetime.today()
+ self._version_identifier = "%dwk%02d" % dt.isocalendar()[0:2]
+ return self._version_identifier
+
+ @property
+ def type(self):
+ if self.meta and self.meta.get('type'):
+ return self.meta['type']
+ else:
+ return 'configurationroot'
+
+class FeatureList(CarbonConfiguration):
+ def __init__(self, ref='', **kwargs):
+ if not kwargs.get('path'):
+ kwargs['path'] = str(kwargs.get('name', '')+'.confml')
+ kwargs['type'] = 'featurelist'
+ super(FeatureList, self).__init__(ref, **kwargs)
+ self.name = kwargs.get('name', '')
+ self._version_identifier = kwargs.get('version_identifier', 'WORKING')
+
+class CarbonFeature(CarbonElement, confmlmodel.ConfmlSetting):
+ def __init__(self, ref,**kwargs):
+ ref = utils.resourceref.to_dottedref(ref)
+ super(CarbonFeature,self).__init__(ref,**kwargs)
+
+
+class CarbonSetting(CarbonFeature, confmlmodel.ConfmlSetting):
+ pass
+
+class CarbonIntSetting(CarbonFeature, confmlmodel.ConfmlIntSetting):
+ pass
+
+class CarbonBooleanSetting(CarbonFeature, confmlmodel.ConfmlBooleanSetting):
+ pass
+
+class CarbonSelectionSetting(CarbonFeature, confmlmodel.ConfmlSelectionSetting):
+ pass
+
+class CarbonStringSetting(CarbonFeature, confmlmodel.ConfmlSetting):
+ def __init__(self, ref,**kwargs):
+ super(CarbonStringSetting,self).__init__(ref,**kwargs)
+ self.type = 'string'
+
+ pass
+
+def get_mapper(modelname):
+ """
+ Return a instance of appropriate mapper for given model.
+ """
+ mapmodule = __import__('cone.carbon.mapping')
+ return mapmodule.carbon.mapping.MAPPERS[modelname]()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/persistentjson.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/persistentjson.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,609 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+import re
+import logging
+import simplejson
+
+""" cone specific imports """
+from cone.public import persistence, exceptions, api, utils, container
+from cone.carbon import model
+
+MODEL = model
+
+def dumps(obj, indent=True):
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = obj._get_mapper('carbon').map_object(obj)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ dict = writer.dumps(mobj)
+ # Return the data as dict, as it is urlencoded by client
+ return dict
+
+def loads(jsonstr):
+ return CarbonReader().loads(jsonstr)
+
+
+class CarbonResourceMapper(object):
+ def __init__(self):
+ self.CARBON_RESOURCE_TYPE_MAP = {'configurationroot' : self.map_carbon_configurationroot,
+ 'configurationlayer' : self.map_carbon_configurationlayer,
+ 'featurelist' : self.map_carbon_featurelist}
+ self.CONFML_RESOURCE_TYPE_MAP = {'configurationroot' : self.map_confml_configurationroot,
+ 'configurationlayer' : self.map_confml_configurationlayer,
+ 'featurelist' : self.map_confml_featurelist}
+
+ def map_carbon_resource(self, resourcepath):
+ for resourceext in self.CARBON_RESOURCE_TYPE_MAP:
+ if resourcepath.endswith(resourceext):
+ return self.CARBON_RESOURCE_TYPE_MAP[resourceext](resourcepath)
+ return resourcepath
+
+ def map_confml_resource(self, resourcetype, resourcepath):
+ return self.CONFML_RESOURCE_TYPE_MAP[resourcetype](resourcepath)
+
+ def map_carbon_configurationroot(self, resourcepath):
+ return resourcepath.replace('.configurationroot', '.confml')
+
+ def map_carbon_configurationlayer(self, resourcepath):
+ return resourcepath.replace('.configurationlayer', '/root.confml')
+
+ def map_carbon_featurelist(self, resourcepath):
+ return "featurelists/%s" % resourcepath.replace('.featurelist', '.confml')
+
+ def map_confml_configurationroot(self, resourcepath):
+ return resourcepath.replace('.confml', '.configurationroot')
+
+ def map_confml_configurationlayer(self, resourcepath):
+ return resourcepath.replace('/root.confml', '.configurationlayer')
+
+ def map_confml_featurelist(self, resourcepath):
+ path = resourcepath.replace('featurelists/','').replace('.confml', '')
+ version_identifier = 'WORKING'
+ m = re.match('^(.*) \((.*)\)', path)
+ # if the resourcepath does not have version information
+ # use default WORKING
+ if m:
+ path = m.group(1)
+ version_identifier = m.group(2)
+ return '%s (%s).featurelist' % (path, version_identifier)
+
+class ResourceListReader(persistence.ConeReader):
+ """
+ """
+ def loads(self, jsonstr):
+ """
+ @param jsonstr: The json string to read.
+ """
+ reslist = model.ResourceList()
+ datadict = simplejson.loads(jsonstr)
+ for configuration in datadict.get('configurations', []):
+ reslist.add_resource(model.ConfigurationResource(**configuration))
+ for featurelist in datadict.get('featurelists', []):
+ reslist.add_resource(model.FeatureListResource(**featurelist))
+ return reslist
+
+class HasResourceReader(persistence.ConeReader):
+ """
+ """
+ def loads(self, jsonstr):
+ """
+ @param jsonstr: The json string to read.
+ """
+ try:
+ datadict = simplejson.loads(jsonstr)
+ return datadict.get('has_resource',False)
+ except ValueError,e:
+ logging.getLogger('cone').error("Failed to parser json from %s" % jsonstr)
+ raise e
+
+
+class CarbonWriter(persistence.ConeWriter):
+ """
+ """
+ def dumps(self, obj):
+ """
+ @param obj: The object
+ """
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = obj._get_mapper('carbon').map_object(obj)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ return writer.dumps(obj)
+
+
+class CarbonReader(persistence.ConeReader):
+ """
+ """
+ def loads(self, jsonstr):
+ """
+ @param xml: The xml which to read. reads only the first object.
+ """
+ try:
+ datadict = simplejson.loads(jsonstr)
+ for key in datadict:
+ reader = get_reader_for_elem(key)
+ return reader.loads(datadict[key])
+ except (SyntaxError, ValueError),e:
+ utils.log_exception(logging.getLogger('cone'), "Json string parse raised exception: %s!" % (e))
+ raise exceptions.ParseError("Json string %s parse raised exception: %s!" % (jsonstr,e))
+
+class ConfigurationCreateWriter(CarbonWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this CarbonWriter supports writing
+ of the given class name
+ """
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ featurelists = []
+ included = []
+ # Remove the featurelists and configurations from the creation phase
+# resmapper = CarbonResourceMapper()
+# for confpath in obj.list_configurations():
+# config = obj.get_configuration(confpath)
+# if config.meta and config.meta.get('type') == 'featurelist':
+# featurelists.append(resmapper.map_confml_resource('featurelist',confpath))
+# elif config.meta and config.meta.get('type'):
+# included.append(resmapper.map_confml_resource(config.meta.get('type'),confpath))
+# else:
+# # ignore configs that are not carbon configs
+# pass
+
+ configuration_dict = {'name' : obj.name,
+ 'parent_path' : '',
+ 'included' : included,
+ 'description' : obj.desc or 'Needs description',
+ 'configuration_type' : 'carbon',
+ 'resource_type' : 'configuration',
+ 'feature_lists' : featurelists,
+ }
+
+ return configuration_dict
+
+class ConfigurationWriter(CarbonWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this CarbonWriter supports writing
+ of the given class name
+ """
+ if classname=="CarbonConfiguration":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ if obj.meta:
+ if obj.meta.get('type') == 'configurationroot':
+ return self.dumps_root(obj)
+ elif obj.meta.get('type') == 'configurationlayer':
+ return self.dumps_layer(obj)
+ raise Exception("Not supported CarbonConfigruration, %s" % obj)
+
+ def dumps_root(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ featurelists = []
+ included = []
+ resmapper = CarbonResourceMapper()
+ for confpath in obj.list_configurations():
+ config = obj.get_configuration(confpath)
+ if config.meta:
+ if config.meta.get('type') == 'featurelist':
+ featurelists.append(resmapper.map_confml_resource('featurelist',confpath))
+ else:
+ included.append(resmapper.map_confml_resource(config.meta.get('type'),confpath))
+ else:
+ # This default case could also be identified as error
+ included.append(confpath)
+
+ configuration_dict = {'feature_lists': featurelists,
+ 'parent_config': None,
+ 'configuration_name': obj.name,
+ 'version_identifier': obj.version_identifier,
+ 'included': included,
+ 'ref': obj.ref}
+
+ return configuration_dict
+
+ def dumps_layer(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ configuration_dict = {'version_identifier': obj.version_identifier}
+
+ datawriter = DataWriter()
+ data = datawriter.dumps(obj)
+ configuration_dict['data'] = data
+
+ return configuration_dict
+
+class ConfigurationRootReader(CarbonReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given elem name
+ """
+ if elemname=="configurationroot":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ pass
+
+ def loads(self, dict):
+ """
+ @param obj: The Configuration object
+ """
+ name = dict.get('configuration_name')
+ path = name + ".confml"
+ conf = model.CarbonConfiguration(dict.get('ref'), path=path, type='configurationroot')
+ conf.name = name
+ conf.version = dict.get('version_identifier')
+ resmapper = CarbonResourceMapper()
+
+ """ Read the featurelists as included configurations """
+ for fealist in dict.get('feature_lists',[]):
+ conf.include_configuration(resmapper.map_carbon_resource(fealist))
+ """ Read the included configurations """
+ for includedconfig in dict.get('included',[]):
+ conf.include_configuration(resmapper.map_carbon_resource(includedconfig))
+ return conf
+
+class ConfigurationLayerReader(CarbonReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given elem name
+ """
+ if elemname=="configurationlayer":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ pass
+
+ def loads(self, dict):
+ """
+ @param obj: The Configuration object
+ """
+ name = dict.get('configuration_name')
+ path = name + ".confml"
+ conf = model.CarbonConfiguration(dict.get('ref'), path=path, type='configurationlayer')
+ conf.name = name
+
+ conf.version = dict.get('version_identifier')
+
+ """ Last read the data of this configuration and add it as a configuration """
+ data_reader = DataReader()
+ datacont = data_reader.loads(dict.get('data', {}))
+ proxy = api.ConfigurationProxy(datacont.path)
+ conf.add_configuration(proxy)
+ proxy._set_obj(datacont)
+
+ return conf
+
+class FeatureListCreateWriter(CarbonWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Feature list create writer is supported only explicitly
+ """
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The FeatureList object
+ """
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = obj._get_mapper('carbon').map_object(obj)
+ featurelist_dict = {'type' : 'featurelist',
+ 'flv_description' : mobj.desc or 'Needs description',
+ 'version_identifier' : mobj.version_identifier
+ }
+ if hasattr(mobj, 'responsible'):
+ featurelist_dict['responsible'] = mobj.responsible
+ return featurelist_dict
+
+class FeatureListWriter(CarbonWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Feature list create writer is supported only explicitly
+ """
+ if classname == 'FeatureList':
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The FeatureList object
+ """
+
+ featurelist_dict = {
+ 'type' : 'featurelist',
+ 'name' : obj.name,
+ 'flv_description' : obj.desc or 'Needs description',
+ 'path' : obj.path,
+ 'features' : []
+ }
+ if obj.meta.get('version_identifier'):
+ featurelist_dict['version_identifier'] = obj.meta.get('version_identifier')
+ # add all features of the featurelist
+ for fearef in obj.list_features():
+ feature = obj.get_feature(fearef)
+ writer = FeatureWriter()
+ feadict = writer.dumps(feature)
+ featurelist_dict['features'].append(feadict)
+
+ return featurelist_dict
+
+class FeatureListReader(CarbonReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given elem name
+ """
+ if elemname=="featurelist":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ pass
+
+ def loads(self, dict):
+ """
+ @param obj: The Configuration object
+ """
+ fealist_expanded = dict.get('expanded')
+ fealist_version = dict.get('version_identifier')
+ fealist_is_latest_version = dict.get('is_latest_version')
+ fealist_list_id = dict.get('list_id')
+ fealist_path = dict.get('path')
+ fealist_version_title = dict.get('version_title')
+ fealist_can_be_released = dict.get('can_be_released')
+ fealist_type = dict.get('type')
+ fealist_has_external_relations = dict.get('is_latest_version')
+
+ # Create a configuration object from the featurelist
+ conf = model.FeatureList(path='featurelists/'+fealist_version_title+'.confml')
+ conf.meta.add('version_identifier', fealist_version)
+
+ for feature in dict.get('features'):
+ reader = FeatureReader()
+ fea = reader.loads(feature)
+ if fea != None:
+ conf.add_feature(fea)
+
+ for feafqr in conf.list_all_features():
+ # Add empty data object to featurelist configuration
+ conf.add_data(api.Data(fqr=feafqr))
+
+ return conf
+
+
+class FeatureWriter(CarbonWriter):
+ CONFML_TO_CARBON_TYPE = {
+ 'boolean' : 'BOOLEAN',
+ 'int' : 'INTEGER',
+ 'selection' : 'SELECTION',
+ 'string' : 'STRING',
+ None : None,
+ '' : ''
+ }
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="Feature" or\
+ classname=="CarbonBooleanSetting" or\
+ classname=="CarbonIntSetting" or\
+ classname=="CarbonStringSetting" or\
+ classname=="CarbonSelectSetting"or\
+ classname=="CarbonSetting":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Feature object
+ """
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = obj._get_mapper('carbon').map_object(obj)
+
+ featuredict = {'type' : 'feature',
+ 'status' : 'APPROVED',
+ 'title' : mobj.name,
+ 'ref' : mobj.ref,
+ 'description' : mobj.desc or 'Needs description',
+ 'responsible' : None,
+ 'value_type' : self.CONFML_TO_CARBON_TYPE[mobj.type],
+ 'children' : []}
+ if featuredict['value_type'] != None:
+ featuredict['type_object'] = 'carbon_feature_type_normal'
+ if mobj.type == 'selection':
+ featuredict['options'] = mobj.options.keys()
+
+ writer = FeatureWriter()
+ for fearef in mobj.list_features():
+ feaobj = obj.get_feature(fearef)
+ childdict = writer.dumps(feaobj)
+ featuredict['children'].append(childdict)
+ return featuredict
+
+
+class FeatureReader(CarbonReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given elem name
+ """
+ if elemname=="features":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ pass
+
+ def loads(self, dict):
+ """
+ @param obj: The Configuration object
+ """
+ id = dict.get('id')
+ name = dict.get('title')
+ ref = dict.get('ref')
+ ref = utils.resourceref.to_objref(ref)
+ status = dict.get('status')
+ value_type = dict.get('value_type')
+ description = dict.get('description')
+
+ if value_type == 'boolean':
+ fea = model.CarbonBooleanSetting(ref, type=value_type)
+ elif value_type == 'integer':
+ fea = model.CarbonIntSetting(ref, type=value_type)
+ elif value_type == 'string':
+ fea = model.CarbonStringSetting(ref, type=value_type)
+ elif value_type == 'selection':
+ fea = model.CarbonSelectionSetting(ref, type=value_type)
+ for option in dict.get('options'):
+ fea.add_option(option,option)
+ elif value_type == '':
+ fea = model.CarbonFeature(ref, type=value_type)
+ else:
+ fea = model.CarbonFeature(ref)
+
+
+ fea.name = name
+ fea.status = status
+ fea.desc = description
+
+ for childdict in dict.get('children',[]):
+ reader = FeatureReader()
+ subfea = reader.loads(childdict)
+ if subfea != None:
+ fea.add_feature(subfea)
+ return fea
+
+class DataWriter(CarbonWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="Data" or \
+ classname=="DataContainer":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The DataContainer object
+ """
+ datadict = {}
+ for dataelem in obj._traverse(type=api.Data):
+ if dataelem.get_value() != None:
+ datadict[dataelem.get_fearef()] = map_confml2carbon_value(dataelem.get_value())
+ return datadict
+
+
+class DataReader(CarbonReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given elem name
+ """
+ if elemname=="data":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ pass
+
+ def loads(self, dict):
+ """
+ @param obj: The Configuration object
+ """
+ datacont = api.Configuration('confml/data.confml')
+ for dataref in dict.keys():
+ # Ignore null values
+ if dict[dataref]:
+ refs = []
+ for elem in dataref.split('.'):
+ refs.append(utils.resourceref.to_objref(elem))
+ newref = '.'.join(refs)
+ dataelem = api.Data(fqr=newref, value=map_carbon2confml_value(dict[dataref]))
+ datacont.add_data(dataelem)
+ return datacont
+
+def map_carbon2confml_value(value):
+ if value == 'DEFINED':
+ return 'true'
+ elif value == 'UNDEFINED':
+ return 'false'
+ else:
+ return value
+
+def map_confml2carbon_value(value):
+ if value == 'true':
+ return 'DEFINED'
+ elif value == 'false':
+ return 'UNDEFINED'
+ else:
+ return value
+
+def get_reader_for_elem(elemname, parent=None):
+ for reader in CarbonReader.__subclasses__():
+ if reader.supported_elem(elemname,parent):
+ return reader()
+ raise exceptions.ConePersistenceError("No reader for given elem %s under %s found!" % (elemname, parent))
+
+def get_writer_for_class(classname):
+ for writer in CarbonWriter.__subclasses__():
+ if writer.supported_class(classname):
+ return writer ()
+ raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+if SOURCE_ROOT not in sys.path:
+ sys.path.append(SOURCE_ROOT)
+
+# Find all unittest_*.py files in this folder
+import re
+__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
+# Strip .py endings
+__all__ = map(lambda name: name[:-3], __all__)
+
+def collect_suite():
+ sys.path.insert(0, ROOT_PATH)
+ try:
+ suite = unittest.TestSuite()
+ for test_module in __all__:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+ finally:
+ del sys.path[0]
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/tests/unittest_mapping.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/tests/unittest_mapping.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import unittest
+import string
+import sys
+import os
+import shutil
+import __init__
+
+from cone.public import api, exceptions
+from cone.confml import model as confmlmodel
+from cone.carbon import persistentjson, model, mapping
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestGetMapper(unittest.TestCase):
+ def test_get_mapper(self):
+ mapper = model.get_mapper('confml')
+ self.assertTrue(isinstance(mapper, mapping.Carbon2confml))
+
+ def test_get_mapper_from_object(self):
+ s = model.CarbonSetting("test")
+ mapper = s._get_mapper('confml')
+ self.assertTrue(isinstance(mapper, mapping.Carbon2confml))
+
+
+class TestCarbon2confml(unittest.TestCase):
+ def test_map_carbon_configuration(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.CarbonConfiguration("test")
+ c2 = mapper.configuration(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlConfiguration))
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlConfiguration))
+
+ def test_map_carbon_featurelist(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.FeatureList(name="test")
+ c2 = mapper.configuration(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlConfiguration))
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlConfiguration))
+
+ def test_map_carbon_configuration_with_data(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.CarbonConfiguration("test")
+ c1.name = "test.confml"
+ c1.namespace = "com.nokia"
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlConfiguration))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.namespace, "com.nokia")
+ self.assertEquals(c2.path, "test")
+
+ def test_map_carbon_setting_with_data(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.CarbonSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_setting_with_data(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.CarbonSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_int_setting_with_data(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.CarbonIntSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlIntSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_setting_with_data(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.CarbonBooleanSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlBooleanSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_setting_with_data(self):
+ mapper = model.get_mapper('confml')
+ c1 = model.CarbonSelectionSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, confmlmodel.ConfmlSelectionSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/carbon/tests/unittest_model.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/tests/unittest_model.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,143 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import unittest
+import string
+import sys
+import os
+import shutil
+import __init__
+import datetime
+
+from cone.public import api, exceptions
+from cone.carbon import persistentjson, model
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestConfigurationResource(unittest.TestCase):
+ def test_create(self):
+ c = model.ConfigurationResource(configuration_name='test')
+ self.assertTrue(c)
+ self.assertEquals(c.name, 'test')
+
+ def test_create_from_dict(self):
+ confdict = {'parent_config': 'hessu', 'path': 'Testing', 'version_identifier': '0.1', 'configuration_name': 'Testing'}
+ c = model.ConfigurationResource(**confdict)
+ self.assertTrue(c)
+ self.assertEquals(c.name, 'Testing')
+ self.assertEquals(c.path, 'Testing')
+ self.assertEquals(c.parent_config, 'hessu')
+ self.assertEquals(c.version, '0.1')
+ self.assertEquals(c.get_path(), 'Testing/root.confml')
+
+class TestFeatureListResource(unittest.TestCase):
+ def test_create(self):
+ c = model.FeatureListResource(path='test', list_id=1, list_version_id=1)
+ self.assertTrue(c)
+ self.assertEquals(c.path, 'test')
+ self.assertEquals(c.list_id, 1)
+ self.assertEquals(c.list_version_id, 1)
+
+ def test_create_from_dict(self):
+ fldict = {
+ "list_version_id": 30,
+ "expanded": True,
+ "version_identifier": "working",
+ "is_latest_version": True,
+ "list_id": 33,
+ "path": "ESTART",
+ "version_title": "ESTART (working)",
+ "can_be_released": True,
+ "type": "featurelist",
+ "has_external_relations": False
+ }
+ c = model.FeatureListResource(**fldict)
+ self.assertTrue(c)
+ self.assertEquals(c.list_version_id, 30)
+ self.assertEquals(c.expanded, True)
+ self.assertEquals(c.version_identifier, "working")
+ self.assertEquals(c.is_latest_version, True)
+ self.assertEquals(c.list_id, 33)
+ self.assertEquals(c.path, 'ESTART')
+ self.assertEquals(c.version_title, "ESTART (working)")
+ self.assertEquals(c.can_be_released, True)
+ self.assertEquals(c.type, "featurelist")
+ self.assertEquals(c.has_external_relations, False)
+
+
+class TestCarbonConfiguration(unittest.TestCase):
+ def test_create_carbon_configuration(self):
+ config = model.CarbonConfiguration(path='foo/bar/test.confml', version_identifier='testing')
+ self.assertEquals(config.version_identifier,'testing')
+ self.assertEquals(config.path,'foo/bar/test.confml')
+ self.assertEquals(config.ref,'foo__bar__test_confml')
+ self.assertEquals(config.name,'test')
+
+ config = model.CarbonConfiguration(ref='foo/bar/test.confml')
+ self.assertEquals(config.path,'foo/bar/test.confml')
+ self.assertEquals(config.ref,'foo__bar__test_confml')
+ self.assertEquals(config.name,'test')
+
+ def test_create_carbon_configuration_with_current_week_version(self):
+ config = model.CarbonConfiguration(path='foo/bar/test.confml')
+ dt = datetime.datetime.today()
+ self.assertEquals(config.version_identifier,"%dwk%02d" % dt.isocalendar()[0:2])
+
+class TestResourceList(unittest.TestCase):
+ def test_create_resource_list(self):
+ rl = model.ResourceList()
+ self.assertTrue(rl != None)
+
+ def test_add_resource(self):
+ rl = model.ResourceList()
+ c = model.ConfigurationResource(**{'parent_config': 'hessu', 'path': 'Testing', 'version_identifier': '0.1', 'configuration_name': 'Testing'})
+ rl.add_resource(c)
+
+ def test_list_resources(self):
+ rl = model.ResourceList()
+ rl.add_resource(model.ConfigurationResource(**{'parent_config': 'hessu', 'path': 'Testing', 'version_identifier': '0.1', 'configuration_name': 'Testing'}))
+ rl.add_resource(model.ConfigurationResource(**{'parent_config': 'hessu', 'path': 'Foobar', 'version_identifier': '0.1', 'configuration_name': 'Foobar'}))
+ self.assertEquals(rl.list_resources(),['Testing/root.confml','Foobar/root.confml'])
+
+ def test_iterate_resources(self):
+ rl = model.ResourceList()
+ rl.add_resource(model.ConfigurationResource(**{'parent_config': 'hessu', 'path': 'Testing', 'version_identifier': '0.1', 'configuration_name': 'Testing'}))
+ rl.add_resource(model.ConfigurationResource(**{'parent_config': 'hessu', 'path': 'Foobar', 'version_identifier': '0.1', 'configuration_name': 'Foobar'}))
+ for res in rl:
+ self.assertTrue(isinstance(res,model.ConfigurationResource))
+
+class TestFeatureList(unittest.TestCase):
+ def test_create(self):
+ c = model.FeatureList(name='test')
+ self.assertTrue(c)
+ self.assertEquals(c.name, 'test')
+ self.assertEquals(c.meta.get('type'), 'featurelist')
+ self.assertEquals(c.path, 'test.confml')
+
+ def test_create_with_path(self):
+ c = model.FeatureList(path='featurelists/test.confml')
+ self.assertTrue(c)
+ self.assertEquals(c.name, '')
+ self.assertEquals(c.meta.get('type'), 'featurelist')
+ self.assertEquals(c.path, 'featurelists/test.confml')
+ self.assertEquals(c.version_identifier, 'WORKING')
+
+class TestFeature(unittest.TestCase):
+ def test_create(self):
+ c = model.CarbonFeature(ref='test')
+ self.assertTrue(c)
+ self.assertEquals(c.name, 'test')
+ self.assertEquals(c.ref, 'test')
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+
+__all__ = ["implml"]
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/confmltree.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/confmltree.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+try:
+ from elementtree.ElementTree import *
+except ImportError:
+ from xml.etree.ElementTree import *
+
+
+class ElementTreeNs(ElementTree):
+ """
+ A class inherited from elementtree.ElementTree that can write
+ xml elements with qualified names. The xml namespaces that are defined
+ to the self.namespases are written out to the root element of the given
+ root element.
+
+ Example:
+
+ elem = ElementTreeNs.Element('{http://www.test.com}test')
+ etreens = ElementTreeNs(elem, None, {'foo' : 'http://www.test.com'})
+ outf = open('test.xml','w')
+ ElementTreeNs.write(outf)
+
+ content of test.xml would be
+
+ """
+ def __init__(self, element=None, file=None, namespaces={}):
+ ElementTree.__init__(self, element, file)
+ self.namespaces = namespaces
+
+ def write(self, file, encoding="us-ascii"):
+ """
+ Writes the element tree to a file, as XML with the existing namespaces
+
+ @param file A file name, or a file object opened for writing.
+ @param encoding Optional output encoding (default is US-ASCII).
+ """
+ assert self._root is not None
+ if not hasattr(file, "write"):
+ file = open(file, "wb")
+ if not encoding:
+ encoding = "us-ascii"
+ elif encoding != "utf-8" and encoding != "us-ascii":
+ file.write("\n" % encoding)
+ # set the namespaces for the root element
+ for ns in self.namespaces:
+ self._root.set('xmlns:%s' % self.namespaces[ns], ns)
+ self._write(file, self._root, encoding, self.namespaces)
+
+
+def tostring(element, namespaces, encoding=None):
+ """
+ """
+ class dummy:
+ pass
+ data = []
+ file = dummy()
+ file.write = data.append
+ ElementTreeNs(element, None, namespaces).write(file, encoding)
+ return "".join(data)
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/implml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/implml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys
+import os
+
+from cone.public import plugin, utils, exceptions
+
+debug = 0
+
+class Implml(plugin.ImplBase):
+ """
+ Base class for any implementation plugin.
+ """
+ def __init__(self,ref,configuration,output='output'):
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.set_output_root(output)
+ pass
+
+ def list_output_files(self):
+ return utils.list_files(self.output)
+
+
+ def has_ref(self, refs):
+ """
+ Return True if the implementation uses the given ref as input value. Otherwise return False.
+ """
+ raise exceptions.NotSupportedException()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/mapping.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/mapping.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,86 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+
+"""
+Methods for Mapping Carbon model to other data model objects
+"""
+from cone.public import api, exceptions, container, utils
+from cone.public.mapping import BaseMapper
+from cone.carbon import model as carbonmodel
+
+""" Carbon to confml model mapping is done in Carbon2confml """
+from cone.confml import model
+
+class Confml2carbon(object):
+ """
+ Carbon2confml class maps Carbon model object to confml model objects.
+ """
+ def __init__(self):
+ self.MAPPING_TABLE = {model.ConfmlConfiguration: self.configuration,
+ model.ConfmlFeature: self.setting,
+ model.ConfmlSetting: self.setting,
+ model.ConfmlIntSetting: self.setting,
+ model.ConfmlBooleanSetting: self.setting,
+ model.ConfmlSelectionSetting: self.setting}
+ pass
+
+ def map_object(self, object):
+ """
+ Return a confml model object from Carbon object
+ """
+ try:
+ return self.MAPPING_TABLE[object.__class__](object)
+ except KeyError:
+ return object
+
+ def configuration(self, object):
+ """
+ Map a CarbonConfiguration object to a ConfmlConfiguration
+ """
+ mapdict = object._dict()
+ if object.meta and object.meta.get('type') == 'featurelist':
+ mapobj = object._clone(class_instance=carbonmodel.FeatureList, recursion=True)
+ else:
+ mapobj = object._clone(class_instance=carbonmodel.CarbonConfiguration, recursion=True)
+ return mapobj
+
+ def setting(self, object):
+ """
+ Map a CarbonSetting object to a ConfmlSetting
+ """
+ mapdict = object._dict()
+ if object.__class__ == model.ConfmlFeature:
+ mapobj = object._clone(class_instance=carbonmodel.CarbonFeature, recursion=True)
+ elif object.__class__ == model.ConfmlIntSetting:
+ mapobj = object._clone(class_instance=carbonmodel.CarbonIntSetting, recursion=True)
+ elif object.__class__ == model.ConfmlBooleanSetting:
+ mapobj = object._clone(class_instance=carbonmodel.CarbonBooleanSetting, recursion=True)
+ elif object.__class__ == model.ConfmlSelectionSetting:
+ mapobj = object._clone(class_instance=carbonmodel.CarbonSelectionSetting, recursion=True)
+ elif object.__class__ == model.ConfmlSetting:
+ mapobj = object._clone(class_instance=carbonmodel.CarbonSetting, recursion=True)
+ else:
+ raise exceptions.IncorrectClassError('Cannot find a mapping object for this class %s!' % object.__class__)
+ return mapobj
+
+MAPPERS = \
+{ 'carbon' : Confml2carbon,
+ 'confml' : BaseMapper
+}
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/model.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/model.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,982 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Base class for Confml elements.
+Attributes:
+ All Confml element attributes become attributes of this instance.
+"""
+import types
+from cone.public import api, exceptions, container, utils
+
+class ConfmlElement(api.Base):
+ def _get_mapper(self,modelname):
+ """
+ Return a instance of appropriate mapper for given model.
+ """
+ mapmodule = __import__('cone.confml.mapping')
+ return mapmodule.confml.mapping.MAPPERS[modelname]()
+
+ def get_desc(self):
+ try:
+ desc = getattr(self,ConfmlDescription.refname)
+ return desc.text
+ except AttributeError:
+ return None
+
+ def set_desc(self,value):
+ self._add(ConfmlDescription(value))
+
+ def del_desc(self):
+ try:
+ self._remove(ConfmlDescription.refname)
+ except exceptions.NotFound:
+ pass
+ """ The description as a property """
+ desc = property(get_desc,set_desc,del_desc)
+class ConfmlConfiguration(ConfmlElement, api.Configuration):
+ """
+ Confml configuration class.
+ """
+ def __init__(self,ref="", **kwargs):
+ super(ConfmlConfiguration,self).__init__(ref, **kwargs)
+ if kwargs.get('meta'):
+ self.meta = kwargs.get('meta')
+ if kwargs.get('desc'):
+ self.desc = kwargs.get('desc')
+
+
+ def get_desc(self):
+ """
+ @return: The description of the Configuration.
+ """
+ try:
+ desc = getattr(self,ConfmlDescription.refname)
+ return desc.text
+ except AttributeError:
+ return None
+
+ def set_desc(self,value):
+ self._add(ConfmlDescription(value))
+
+ def del_desc(self):
+ try:
+ self._remove(ConfmlDescription.refname)
+ except exceptions.NotFound:
+ pass
+
+ """ The description as a property """
+ desc = property(get_desc,set_desc,del_desc)
+
+ def get_meta(self):
+ """
+ @return: The description of the Configuration.
+ """
+ try:
+ meta = getattr(self,ConfmlMeta.refname)
+ return meta
+ except AttributeError:
+ return None
+
+ def set_meta(self,value):
+ self._add(ConfmlMeta(value))
+
+ def del_meta(self):
+ try:
+ self._remove(ConfmlMeta.refname)
+ except exceptions.NotFound:
+ pass
+
+ """ The meta element as a property """
+ meta = property(get_meta,set_meta,del_meta)
+
+
+class ConfmlGroup(ConfmlElement, api.Group):
+ """
+ Confml view.
+ """
+ def __init__(self, ref="", **kwargs):
+ super(ConfmlGroup,self).__init__(ref,**kwargs)
+ if kwargs.get('icon'):
+ self.icon = kwargs.get('icon')
+ if kwargs.get('desc'):
+ self.desc = kwargs.get('desc')
+
+ def get_icon(self):
+ try:
+ icon = getattr(self,ConfmlIcon.refname)
+ return icon.href
+ except AttributeError:
+ return None
+ def set_icon(self,value): self._add(ConfmlIcon(value))
+ def del_icon(self):
+ try:
+ self._remove(ConfmlIcon.refname)
+ except exceptions.NotFound:
+ pass
+ """ The icon as a property """
+ icon = property(get_icon,set_icon,del_icon)
+
+ def get_desc(self):
+ try:
+ desc = getattr(self,ConfmlDescription.refname)
+ return desc.text
+ except AttributeError:
+ return None
+ def set_desc(self,value): self._add(ConfmlDescription(value))
+ def del_desc(self):
+ try:
+ self._remove(ConfmlDescription.refname)
+ except exceptions.NotFound:
+ pass
+ """ The description as a property """
+ desc = property(get_desc,set_desc,del_desc)
+
+
+class ConfmlView(api.View):
+ """
+ Confml view.
+ """
+ def __init__(self, ref="", **kwargs):
+ super(ConfmlView,self).__init__(ref,**kwargs)
+ if kwargs.get('desc'):
+ self.desc = kwargs.get('desc')
+
+
+ def get_desc(self):
+ try:
+ desc = getattr(self,ConfmlDescription.refname)
+ return desc.text
+ except AttributeError:
+ return None
+ def set_desc(self,value): self._add(ConfmlDescription(value))
+ def del_desc(self):
+ try:
+ self._remove(ConfmlDescription.refname)
+ except exceptions.NotFound:
+ pass
+ """ The description as a property """
+ desc = property(get_desc,set_desc,del_desc)
+
+class ConfmlFeature(ConfmlElement, api.Feature):
+ pass
+
+class ConfmlSetting(ConfmlElement, api.Feature):
+ """
+ Confml setting class. Attribute 'options' contains options of this setting.
+ """
+ supported_types = ['int',
+ 'string',
+ 'boolean',
+ 'selection']
+ def __init__(self, ref,**kwargs):
+ super(ConfmlSetting,self).__init__(ref,**kwargs)
+ self.type = kwargs.get('type',None)
+ if kwargs.get('desc'):
+ self.desc = kwargs.get('desc')
+ if kwargs.get('minOccurs'):
+ self.minOccurs = kwargs.get('minOccurs')
+ if kwargs.get('maxOccurs'):
+ self.maxOccurs = kwargs.get('maxOccurs')
+ if kwargs.get('maxLength'):
+ self.maxLength = kwargs.get('maxLength')
+ if kwargs.get('minLength'):
+ self.minLength = kwargs.get('minLength')
+ if kwargs.get('mapKey'):
+ self.mapKey = kwargs.get('mapKey')
+ if kwargs.get('mapValue'):
+ self.mapValue = kwargs.get('mapValue')
+
+ self.readOnly = kwargs.get('readOnly',None)
+ self.constraint = kwargs.get('constraint',None)
+ self.required = kwargs.get('required',None)
+ self.relevant = kwargs.get('relevant',None)
+
+ def get_valueset(self):
+ """
+ Get the ValueSet object for this feature, that has the list of available values.
+ """
+ return api.ValueRe('.*')
+
+ def add_property(self, **kwargs):
+ """
+ @param name=str: property name
+ @param value=str: property value
+ @param unit=str: property unit, e.g. kB
+ """
+ self._add(ConfmlProperty(**kwargs), container.APPEND)
+
+ def get_property(self, name):
+ """
+ @param name: The name of the property
+ """
+ for property in utils.get_list(self._get(ConfmlProperty.refname)):
+ if property.name == name:
+ return property
+ raise exceptions.NotFound("ConfmlProperty with name %s not found!" % name)
+
+ def remove_property(self, name):
+ """
+ remove a given option from this feature by name.
+ @param name:
+ """
+ for property in self._get(ConfmlProperty.refname):
+ if property.name == name:
+ return self._remove(property.get_fullref())
+ raise exceptions.NotFound("ConfmlProperty with name %s not found!" % name)
+
+ def list_properties(self):
+ """
+ Return a array of all Feature children references under this object.
+ """
+ return [obj.name for obj in utils.get_list(self._get(ConfmlProperty.refname))]
+
+ def get_maxlength(self):
+ try:
+ return getattr(self,ConfmlMaxLength.refname).value
+ except AttributeError:
+ return None
+
+ def set_maxlength(self,value):
+ self._add(ConfmlMaxLength(value))
+
+ def del_maxlength(self):
+ try:
+ self._remove(ConfmlMaxLength.refname)
+ except exceptions.NotFound:
+ pass
+ """ The description as a property """
+ maxLength = property(get_maxlength,set_maxlength,del_maxlength)
+
+ def get_minlength(self):
+ try:
+ return getattr(self,ConfmlMinLength.refname).value
+ except AttributeError:
+ return None
+
+ def set_minlength(self,value):
+ self._add(ConfmlMinLength(value))
+
+ def del_minlength(self):
+ try:
+ self._remove(ConfmlMinLength.refname)
+ except exceptions.NotFound:
+ pass
+ """ The description as a property """
+ minLength = property(get_minlength,set_minlength,del_minlength)
+
+ def get_minInclusive(self):
+ try:
+ return getattr(self,ConfmlMinInclusive.refname).value
+ except AttributeError:
+ return None
+
+ def set_minInclusive(self,value):
+ self._add(ConfmlMinInclusive(value))
+
+ def del_minInclusive(self):
+ try:
+ self._remove(ConfmlMinInclusive.refname)
+ except exceptions.NotFound:
+ pass
+ """ The minInclusive as a property """
+ minInclusive = property(get_minInclusive,set_minInclusive,del_minInclusive)
+
+ def get_maxInclusive(self):
+ try:
+ return getattr(self,ConfmlMaxInclusive.refname).value
+ except AttributeError:
+ return None
+
+ def set_maxInclusive(self,value):
+ self._add(ConfmlMaxInclusive(value))
+
+ def del_maxInclusive(self):
+ try:
+ self._remove(ConfmlMaxInclusive.refname)
+ except exceptions.NotFound:
+ pass
+ """ The minInclusive as a property """
+ maxInclusive = property(get_maxInclusive,set_maxInclusive,del_maxInclusive)
+
+ def get_minExclusive(self):
+ try:
+ return getattr(self,ConfmlMinExclusive.refname).value
+ except AttributeError:
+ return None
+
+ def set_minExclusive(self,value):
+ self._add(ConfmlMinExclusive(value))
+
+ def del_minExclusive(self):
+ try:
+ self._remove(ConfmlMinExclusive.refname)
+ except exceptions.NotFound:
+ pass
+ """ The minExclusive as a property """
+ minExclusive = property(get_minExclusive,set_minExclusive,del_minExclusive)
+
+ def get_maxExclusive(self):
+ try:
+ return getattr(self,ConfmlMaxExclusive.refname).value
+ except AttributeError:
+ return None
+
+ def set_maxExclusive(self,value):
+ self._add(ConfmlMaxExclusive(value))
+
+ def del_maxExclusive(self):
+ try:
+ self._remove(ConfmlMaxExclusive.refname)
+ except exceptions.NotFound:
+ pass
+ """ The maxExclusive as a property """
+ maxExclusive = property(get_maxExclusive,set_maxExclusive,del_maxExclusive)
+
+ def get_pattern(self):
+ try:
+ return getattr(self,ConfmlPattern.refname).value
+ except AttributeError:
+ return None
+
+ def set_pattern(self,value):
+ self._add(ConfmlPattern(value))
+
+ def del_pattern(self):
+ try:
+ self._remove(ConfmlPattern.refname)
+ except exceptions.NotFound:
+ pass
+ """ The pattern as a property """
+ pattern = property(get_pattern,set_pattern,del_pattern)
+
+ def get_totalDigits(self):
+ try:
+ return getattr(self,ConfmlTotalDigits.refname).value
+ except AttributeError:
+ return None
+
+ def set_totalDigits(self,value):
+ self._add(ConfmlTotalDigits(value))
+
+ def del_totalDigits(self):
+ try:
+ self._remove(ConfmlTotalDigits.refname)
+ except exceptions.NotFound:
+ pass
+ """ The totalDigits as a property """
+ totalDigits = property(get_totalDigits,set_totalDigits,del_totalDigits)
+
+ @property
+ def options(self):
+ optdict = {}
+ for opt in self._objects(type=api.Option):
+ optdict[opt.value] = opt
+ return optdict
+
+ @property
+ def properties(self):
+ dict = {}
+ for property in utils.get_list(self._get(ConfmlProperty.refname)):
+ dict[property.name] = property
+ return dict
+
+ def get_rfs(self,):
+ return super(ConfmlSetting,self).get_value('rfs')
+
+ def set_rfs(self, value):
+ super(ConfmlSetting,self).set_value('rfs',value)
+
+ def del_rfs(self):
+ super(ConfmlSetting,self).del_value('rfs')
+
+ rfs = property(get_rfs,set_rfs,del_rfs)
+
+ def get_value_cast(self, value, attr=None):
+ """
+ A function to perform the value type casting in get operation
+ @param value: the value to cast
+ @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
+ """
+ if not attr or attr == 'data':
+ return self.get_data_cast(value)
+ elif attr == 'rfs':
+ return self.get_rfs_cast(value)
+ else:
+ return value
+
+ def set_value_cast(self, value, attr=None):
+ """
+ A function to perform the value type casting in the set operation
+ @param value: the value to cast
+ @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
+ """
+ if not attr or attr == 'data':
+ return self.set_data_cast(value)
+ elif attr == 'rfs':
+ return self.set_rfs_cast(value)
+ else:
+ return value
+
+ def get_data_cast(self, value):
+ """
+ A function to perform the data type casting in get operation
+ @param value: the value to cast
+ """
+ return value
+
+ def set_data_cast(self, value):
+ """
+ A function to perform the data type casting in the set operation
+ @param value: the value to cast
+ """
+ return value
+
+ def get_rfs_cast(self, value):
+ """
+ A function to perform the rfs type casting in get operation
+ @param value: the value to cast
+ """
+ if value == 'true':
+ return True
+ elif value == 'false':
+ return False
+ else: # otherwise this is an invalid rfs value. Should it report an error?
+ return value
+
+ def set_rfs_cast(self, value):
+ """
+ A function to perform the rfs type casting in the set operation
+ @param value: the value to cast
+ """
+ if value:
+ return 'true'
+ else:
+ return 'false'
+
+
+class ConfmlStringSetting(ConfmlSetting):
+ """
+ Confml setting class for integer type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'string'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+
+class ConfmlIntSetting(ConfmlSetting):
+ """
+ Confml setting class for integer type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'int'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+ def get_valueset(self):
+ """
+ Get the ValueSet object for this feature, that has the list of available values.
+ """
+ return api.ValueRange(0,sys.maxint)
+
+ def get_data_cast(self, value):
+ """
+ A function to perform the value type casting in get operation
+ """
+ if value:
+ try:
+ return int(value)
+ except ValueError:
+ return int(value, 16)
+ else:
+ return value
+
+ def set_data_cast(self, value):
+ """
+ A function to perform the value type casting in the set operation
+ """
+ return str(int(value))
+
+
+class ConfmlRealSetting(ConfmlSetting):
+ """
+ Confml setting class for real type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'real'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+ def get_valueset(self):
+ """
+ Get the ValueSet object for this feature, that has the list of available values.
+ """
+ return api.ValueRange(0,float(sys.maxint))
+
+ def get_data_cast(self, value):
+ """
+ A function to perform the value type casting in get operation
+ """
+ if value:
+ return float(value)
+ else:
+ return value
+
+ def set_data_cast(self, value):
+ """
+ A function to perform the value type casting in the set operation
+ """
+ return str(float(value))
+
+
+
+
+class ConfmlBooleanSetting(ConfmlSetting):
+ """
+ Confml setting class for boolean type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'boolean'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+ def get_valueset(self):
+ """
+ Get the ValueSet object for this feature, that has the list of available values.
+ """
+ return api.ValueSet([True,False])
+
+ def get_data_cast(self, value):
+ """
+ A function to perform the value type casting in get operation
+ """
+ if value:
+ if value in ('true', '1'):
+ return True
+ else:
+ return False
+ else:
+ return value
+
+ def set_data_cast(self, value):
+ """
+ A function to perform the value type casting in the set operation
+ """
+ if isinstance(value, basestring):
+ if value in ('false', '0'):
+ return 'false'
+ elif value in ('true', '1'):
+ return 'true'
+
+ return str(bool(value)).lower()
+
+
+class ConfmlSelectionSetting(ConfmlSetting):
+ """
+ Confml setting class for boolean type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'selection'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+ def get_valueset(self):
+ """
+ Get the ValueSet object for this feature, that has the list of available values.
+ """
+ return api.Feature.get_valueset(self)
+
+class ConfmlMultiSelectionSetting(ConfmlSetting):
+ """
+ Confml setting class for multiSelection type.
+ """
+
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'multiSelection'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+
+ def get_valueset(self):
+ """
+ Get the ValueSet object for this feature, that has the list of available values.
+ """
+ return api.Feature.get_valueset(self)
+
+ def get_data_cast(self, value):
+ """
+ A function to perform the value type casting in get operation
+ """
+ try:
+ if not isinstance(value, types.ListType):
+ values = value.split('" "')
+ for i in range(len(values)):
+ if values[i].startswith('"'):
+ values[i] = values[i][1:]
+ if values[i].endswith('"'):
+ values[i] = values[i][:-1]
+ return values
+ return value
+ except AttributeError:
+ return None
+
+ def set_data_cast(self, value):
+ """
+ A function to perform the value type casting in the set operation
+ """
+
+ if isinstance(value, list):
+ value = " ".join(['"%s"' % elem for elem in value])
+ return value
+
+ def set_value(self, value):
+ if not isinstance(value, types.ListType):
+ raise ValueError("Only list types are allowed.")
+ self.value = value
+
+class ConfmlDateSetting(ConfmlSetting):
+ """
+ Confml setting class for date type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'date'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+class ConfmlTimeSetting(ConfmlSetting):
+ """
+ Confml setting class for time type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'time'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+class ConfmlDateTimeSetting(ConfmlSetting):
+ """
+ Confml setting class for date-time type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'dateTime'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+class ConfmlDurationSetting(ConfmlSetting):
+ """
+ Confml setting class for date type.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'duration'
+ ConfmlSetting.__init__(self,ref,**kwargs)
+
+class ConfmlSequenceSetting(api.FeatureSequence,ConfmlSetting):
+ """
+ Confml setting class. Attribute 'options' contains options of this setting.
+ """
+ def __init__(self, ref,**kwargs):
+ ConfmlSetting.__init__(self,ref,**kwargs)
+ api.FeatureSequence.__init__(self,ref,**kwargs)
+
+class ConfmlFileSetting(ConfmlSetting):
+ """
+ Confml file setting class.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'file'
+ ConfmlSetting.__init__(self, ref, **kwargs)
+ """
+ The file element always includes localPath and targetPath child elements.
+ """
+ self.add_feature(ConfmlLocalPath())
+ self.add_feature(ConfmlTargetPath())
+
+class ConfmlFolderSetting(ConfmlSetting):
+ """
+ Confml folder setting class.
+ """
+ def __init__(self, ref,**kwargs):
+ kwargs['type'] = 'folder'
+ ConfmlSetting.__init__(self, ref, **kwargs)
+ """
+ The folder element always includes localPath and targetPath child elements.
+ """
+ self.add_feature(ConfmlLocalPath())
+ self.add_feature(ConfmlTargetPath())
+
+class ConfmlLocalPath(ConfmlElement, api.Feature):
+ """
+ Confml file class. Attribute setting.
+ """
+ def __init__(self, ref='localPath', **kwargs):
+ kwargs['type'] = 'string'
+ ConfmlElement.__init__(self, **kwargs)
+ api.Feature.__init__(self, ref, **kwargs)
+ self.readOnly = kwargs.get('readOnly', None)
+
+
+class ConfmlTargetPath(ConfmlElement, api.Feature):
+ """
+ Confml file class. Attribute setting.
+ """
+ def __init__(self, ref='targetPath', **kwargs):
+ kwargs['type'] = 'string'
+ ConfmlElement.__init__(self, **kwargs)
+ api.Feature.__init__(self, ref, **kwargs)
+ self.readOnly = kwargs.get('readOnly', None)
+
+
+class ConfmlMeta(api.Base):
+ """
+ Confml meta element
+ """
+ refname = "_meta"
+ def __init__(self, array=None, **kwargs):
+ super(ConfmlMeta,self).__init__(self.refname)
+ self.array = []
+ if array:
+ self.array += array
+
+ def __getitem__(self, key):
+ return self.array[key]
+
+ def __delitem__(self, key):
+ del self.array[key]
+
+ def __setitem__(self, key, value):
+ self.array[key] = value
+
+ def __str__(self):
+ tempstr = "ConfmlMeta object\n"
+ counter = 0
+ for item in self.array:
+ tempstr += "\t%d: %s\n" % (counter, item.__str__())
+ counter += 1
+ return tempstr
+
+ def __cmp__(self, other):
+ try:
+ for item in self.array:
+ if item != other.array[self.array.index(item)]:
+ return 1
+ except:
+ return 1
+ return 0
+
+ def append(self, value):
+ self.array.append(value)
+
+ def add(self, tag, value, ns=None, attributes=None):
+ self.array.append(ConfmlMetaProperty(tag, value, ns, attrs=attributes))
+
+ def get(self, tag, default=None):
+ """
+ Try to find the element by its tag in the meta elem array.
+ @param tag: the tag that is searched,
+ @param default: return the default value if the element is not found.
+ @return: the value of the ConfmlMetaProperty object if it is found. Default value
+ if element with tag is not found.
+ """
+ for item in self.array:
+ if item.tag == tag:
+ return item.value
+ return default
+
+ def replace(self, index, tag, value, ns=None, dict=None):
+ self.array[index] = ConfmlMetaProperty(tag, value, ns, attrs=dict)
+
+ def clear(self, value):
+ self.array = []
+
+ def clone(self):
+ newMeta = ConfmlMeta()
+ for item in self.array:
+ newProp = ConfmlMetaProperty(item.tag, item.value, item.ns, attrs = item.attrs)
+ newMeta.append(newProp)
+ return newMeta
+
+ def find_by_tag(self, value):
+ for item in self.array:
+ if item.tag == value:
+ return self.array.index(item)
+ return -1
+
+ def find_by_attribute(self, name, value):
+ for item in self.array:
+ if item.attrs.has_key(name) and item.attrs[name] == value:
+ return self.array.index(item)
+ return -1
+
+ def get_property_by_tag(self, tag):
+ """
+ Try to find the element by its tag in the meta elem array.
+ @param tag: the tag that is searched
+ @return: the ConfmlMetaProperty object if it is found. None if element with tag is not found.
+ """
+ for item in self.array:
+ if item.tag == tag:
+ return item
+ return None
+
+
+class ConfmlDescription(api.Base):
+ """
+ Confml description element
+ """
+ refname = "_desc"
+ def __init__(self, text=None, **kwargs):
+ super(ConfmlDescription,self).__init__(self.refname)
+ self.text = text or ''
+
+
+class ConfmlIcon(api.Base):
+ """
+ Confml icon element
+ """
+ refname = "_icon"
+ def __init__(self, href='', **kwargs):
+ super(ConfmlIcon,self).__init__(self.refname)
+ self.href = href
+
+
+class ConfmlProperty(api.Base):
+ """
+ Confml meta element
+ """
+ refname = "_property"
+ def __init__(self, **kwargs):
+ """
+ @param name=str: name string
+ @param value=str: value for the property, string
+ @param unit=str: unit of the property
+ """
+ super(ConfmlProperty,self).__init__(self.refname)
+ self.name = kwargs.get('name',None)
+ self.value = kwargs.get('value',None)
+ self.unit = kwargs.get('unit',None)
+
+
+class ConfmlMetaProperty(api.Base):
+ """
+ Confml meta property element
+ """
+ refname = "_metaproperty"
+ def __init__(self, tag, value = None, ns = None, **kwargs):
+ """
+ """
+ super(ConfmlMetaProperty,self).__init__(self.refname)
+ self.tag = tag
+ self.value = value
+ self.ns = ns
+ if kwargs.has_key("attrs") and kwargs["attrs"] != None:
+ self.attrs = dict(kwargs["attrs"])
+ else:
+ self.attrs = {}
+
+ def __cmp__(self, other):
+ try:
+ if self.tag != other.tag or self.value != other.value\
+ or self.ns != other.ns or self.attrs != other.attrs:
+ return 1
+ except:
+ return 1
+ return 0
+
+ def __str__(self):
+ return "Tag: %s Value: %s Namespace: %s Attributes: % s" % (self.tag, self.value, self.ns, repr(self.attrs))
+
+
+
+class ConfmlLength(api.Base):
+ """
+ Confml length element
+ """
+ refname = "_length"
+ def __init__(self, value, **kwargs):
+ super(ConfmlLength,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlMaxLength(api.Base):
+ """
+ Confml max element
+ """
+ refname = "_maxLength"
+ def __init__(self, value, **kwargs):
+ super(ConfmlMaxLength,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlMinLength(api.Base):
+ """
+ Confml min element
+ """
+ refname = "_minLength"
+ def __init__(self, value, **kwargs):
+ super(ConfmlMinLength,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlMinInclusive(api.Base):
+ """
+ Confml minInclusive element
+ """
+ refname = "_minInclusive"
+ def __init__(self, value, **kwargs):
+ super(ConfmlMinInclusive,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlMaxInclusive(api.Base):
+ """
+ Confml minInclusive element
+ """
+ refname = "_maxInclusive"
+ def __init__(self, value, **kwargs):
+ super(ConfmlMaxInclusive,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlMinExclusive(api.Base):
+ """
+ Confml minExclusive element
+ """
+ refname = "_minExclusive"
+ def __init__(self, value, **kwargs):
+ super(ConfmlMinExclusive,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlMaxExclusive(api.Base):
+ """
+ Confml maxExclusive element
+ """
+ refname = "_maxExclusive"
+ def __init__(self, value, **kwargs):
+ super(ConfmlMaxExclusive,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlPattern(api.Base):
+ """
+ Confml pattern element
+ """
+ refname = "_pattern"
+ def __init__(self, value, **kwargs):
+ super(ConfmlPattern,self).__init__(self.refname)
+ self.value = value
+
+class ConfmlTotalDigits(api.Base):
+ """
+ Confml totalDigits element
+ """
+ refname = "_totalDigits"
+ def __init__(self, value, **kwargs):
+ super(ConfmlTotalDigits,self).__init__(self.refname)
+ self.value = value
+
+def get_mapper(modelname):
+ """
+ Return a instance of appropriate mapper for given model.
+ """
+ mapmodule = __import__('cone.confml.mapping')
+ return mapmodule.confml.mapping.MAPPERS[modelname]()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/persistentconfml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/persistentconfml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1164 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import re
+import logging
+import xml.parsers.expat
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+""" cone specific imports """
+from cone.public import persistence, exceptions, api, utils, container
+from cone.confml import model
+
+CONFIGURATION_NAMESPACES = ["http://www.s60.com/xml/confml/2","http://www.s60.com/xml/confml/1"]
+INCLUDE_NAMESPACES = ["http://www.w3.org/2001/XInclude","http://www.w3.org/2001/xinclude"]
+XLINK_NAMESPACES = ["http://www.w3.org/1999/xlink"]
+SCHEMA_NAMESPACES = ["http://www.w3.org/2001/XMLSchema"]
+CV_NAMESPACE = {"http://www.nokia.com/xml/cpf-id/1": "cv"}
+MODEL = model
+
+def dumps(obj, indent=True):
+ etree = ConfmlWriter().dumps(obj)
+ if indent:
+ persistence.indent(etree)
+ return ElementTree.tostring(etree)
+
+def loads(xml):
+ return ConfmlReader().loads(xml)
+
+
+
+class ConfmlWriter(persistence.ConeWriter):
+ """
+ """
+ def dumps(self, obj):
+ """
+ @param obj: The object
+ """
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = obj._get_mapper('confml').map_object(obj)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ return writer.dumps(obj)
+
+class ConfmlReader(persistence.ConeReader):
+ """
+ """
+ def loads(self, xmlstr):
+ """
+ @param xml: The xml which to read. reads only the first object.
+ """
+ reader = get_reader_for_elem("configuration")
+ etree = utils.etree.fromstring(xmlstr)
+ return reader.loads(etree)
+
+
+class ConfigurationWriter(ConfmlWriter):
+ """
+ Writes a single Configuration project confml file.
+ """
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="Configuration" or \
+ classname=="ConfmlConfiguration" :
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ self.configuration_namespace = CONFIGURATION_NAMESPACES[0]
+ self.include_namespace = INCLUDE_NAMESPACES[0]
+ self.xlink_namespace = XLINK_NAMESPACES[0]
+ self.schema_namespace = SCHEMA_NAMESPACES[0]
+
+ def dumps(self,obj,indent=True):
+ elem = ElementTree.Element("configuration")
+ if self.configuration_namespace:
+ elem.set("xmlns",self.configuration_namespace)
+ if self.include_namespace:
+ elem.set("xmlns:xi",self.include_namespace)
+ if self.include_namespace:
+ elem.set("xmlns:xlink",self.xlink_namespace)
+ if self.schema_namespace:
+ elem.set("xmlns:xs",self.schema_namespace)
+ elem.set("name",obj.get_name())
+ for child in obj._objects():
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = child._get_mapper('confml').map_object(child)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ childelem = writer.dumps(child)
+ elem.append(childelem)
+ return elem
+
+
+class ConfigurationReader(ConfmlReader):
+ """
+ Parses a single CPF configuration project root confml file. Parses the XInclude statements to
+ find out the layers inside the project
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given elem name
+ """
+ if elemname=="configuration":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ self.configuration_namespaces = CONFIGURATION_NAMESPACES
+ self.include_namespaces = INCLUDE_NAMESPACES
+ self.schema_namespaces = SCHEMA_NAMESPACES
+
+ def loads(self, etree):
+ configuration = model.ConfmlConfiguration("")
+ configuration.set_name(etree.get("name") or 'unknown')
+ configuration.set_ref(etree.get("name") or 'unknown')
+ for elem in etree.getchildren():
+ # At the moment we ignore the namespace of elements
+ (namespace,elemname) = get_elemname(elem.tag)
+ try:
+ reader = get_reader_for_elem(elemname)
+ obj = reader.loads(elem)
+ if obj:
+ configuration.add(obj)
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return configuration
+
+
+class MetaWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlMeta":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+
+ elem = ElementTree.Element("meta")
+ for metaproperty in obj:
+ prefix = CV_NAMESPACE.get(metaproperty.ns, "")
+ if prefix != "":
+ #Including namespace to metadata element as well
+ elem.set(("xmlns:%s" % prefix), metaproperty.ns)
+ childelem = ElementTree.Element(prefix + ":" + metaproperty.tag)
+ else:
+ childelem = ElementTree.Element(metaproperty.tag)
+ if metaproperty.value != None:
+ childelem.text = metaproperty.value
+ for attr in metaproperty.attrs:
+ childelem.set(attr, metaproperty.attrs[attr])
+ elem.append(childelem)
+ return elem
+
+
+class MetaReader(ConfmlReader):
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="meta":
+ return True
+ else:
+ return False
+
+ def loads(self,etree):
+ metaelem = model.ConfmlMeta()
+ for elem in etree.getchildren():
+ (namespace,elemname) = get_elemname(elem.tag)
+ attributes = {}
+ for key in elem.keys():
+ attributes[key] = elem.get(key)
+
+ metaprop = model.ConfmlMetaProperty(elemname, elem.text, namespace, attrs=attributes)
+ metaelem.append(metaprop)
+ return metaelem
+
+
+class DescWriter(ConfmlWriter):
+ """
+ """
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlDescription":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ elem = ElementTree.Element('desc')
+ elem.text = obj.text
+ return elem
+
+
+class DescReader(ConfmlReader):
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlReader supports reading
+ of the given elem name
+ """
+ if elemname=="desc":
+ return True
+ else:
+ return False
+
+ def loads(self,elem):
+ desc = model.ConfmlDescription(elem.text)
+ return desc
+
+class ConfigurationProxyWriter(ConfmlWriter):
+ """
+ """
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfigurationProxy":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ elem = self.to_include(obj.path)
+ return elem
+
+ def to_include(self,include):
+ elem = ElementTree.Element("xi:include",{"href":include})
+ return elem
+
+class ConfigurationProxyReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="include":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+
+ return api.ConfigurationProxy(self.parse_include(elem))
+
+ def parse_include(self,include):
+ #print "Found include %s" % include.get('href').replace('#/','')
+ return include.get('href').replace('#/','')
+
+
+class FeatureWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlFeature" or \
+ classname=="Feature":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ elem = ElementTree.Element('feature',
+ {'ref' : obj.get_ref(),
+ 'name' : obj.get_name()})
+ if obj.get_type():
+ elem.set('type', obj.get_type())
+ for child in obj._objects():
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = child._get_mapper('confml').map_object(child)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ childelem = writer.dumps(child)
+ if childelem != None:
+ elem.append(childelem)
+ return elem
+
+
+class FeatureReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="feature":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ type = elem.get('type')
+ if type == 'sequence':
+ feature = api.FeatureSequence(elem.get('ref'))
+ else:
+ feature = model.ConfmlFeature(elem.get('ref'))
+ if elem.get('name'):
+ feature.set_name(elem.get('name'))
+ feature.set_type(type)
+ for elem in elem.getchildren():
+ # At the moment we ignore the namespace of elements
+ (namespace,elemname) = get_elemname(elem.tag)
+ try:
+ reader = get_reader_for_elem(elemname)
+ obj = reader.loads(elem)
+ feature.add(obj)
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return feature
+
+
+class OptionWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="Option":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Option object
+ """
+
+ objdict = {}
+ if obj.get_name() is not None: objdict['name'] = obj.get_name()
+ if obj.get_value() is not None: objdict['value'] = obj.get_value()
+ if obj.map is not None: objdict['map'] = obj.map
+ if obj.relevant is not None: objdict['relevant'] = obj.relevant
+ elem = ElementTree.Element('option', objdict)
+
+ return elem
+
+
+class OptionReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="option":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ name = elem.get('name')
+ value = elem.get('value')
+ optmap = elem.get('map')
+ if value == None and optmap == None:
+ logging.getLogger('cone').warning("Encountered option with no value")
+ option = None
+ else:
+ option = api.Option(name, value, map=optmap, relevant=elem.get('relevant'))
+ return option
+
+
+class IconWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlIcon":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Option object
+ """
+ elem = ElementTree.Element('icon',
+ {'xlink:href' : obj.href})
+ return elem
+
+
+class IconReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="icon":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ href = elem.get('{%s}href' % XLINK_NAMESPACES[0])
+ obj = model.ConfmlIcon(href)
+ return obj
+
+
+class PropertyWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlProperty":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Option object
+ """
+ elem = ElementTree.Element('property')
+ if obj.name != None:
+ elem.set('name', obj.name)
+ if obj.value != None:
+ elem.set('value', obj.value)
+ if obj.unit != None:
+ elem.set('unit', obj.unit)
+ return elem
+
+
+class PropertyReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="property":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ option = model.ConfmlProperty(name=elem.get('name'),value=elem.get('value'), unit=elem.get('unit'))
+ return option
+
+
+class XmlSchemaFacetWriter(ConfmlWriter):
+ MAPPING = {'ConfmlLength' : 'xs:length',
+ 'ConfmlMinLength' : 'xs:minLength',
+ 'ConfmlMaxLength' : 'xs:maxLength',
+ 'ConfmlMinInclusive' : 'xs:minInclusive',
+ 'ConfmlMaxInclusive' : 'xs:maxInclusive',
+ 'ConfmlMinExclusive' : 'xs:minExclusive',
+ 'ConfmlMaxExclusive' : 'xs:maxExclusive',
+ 'ConfmlPattern' : 'xs:pattern',
+ 'ConfmlTotalDigits' : 'xs:totalDigits'}
+
+ @classmethod
+ def supported_class(cls, classname):
+ return classname in cls.MAPPING
+
+ def dumps(self, obj):
+ """
+ @param obj: The facet object
+ """
+
+ classname = obj.__class__.__name__
+ elem = ElementTree.Element(self.MAPPING[classname])
+ if obj.value != None:
+ elem.set('value', str(obj.value))
+ return elem
+
+class XmlSchemaFacetReader(ConfmlReader):
+ MAPPING = {'length' : model.ConfmlLength,
+ 'minLength' : model.ConfmlMinLength,
+ 'maxLength' : model.ConfmlMaxLength,
+ 'minInclusive' : model.ConfmlMinInclusive,
+ 'maxInclusive' : model.ConfmlMaxInclusive,
+ 'minExclusive' : model.ConfmlMinExclusive,
+ 'maxExclusive' : model.ConfmlMaxExclusive,
+ 'pattern' : model.ConfmlPattern,
+ 'totalDigits' : model.ConfmlTotalDigits}
+
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ return elemname in cls.MAPPING
+
+ def loads(self, elem):
+ """
+ @param elem: The XML schema facet element
+ """
+ elem_name = utils.xml.split_tag_namespace(elem.tag)[1]
+ facet_class = self.MAPPING[elem_name]
+ obj = facet_class(elem.get('value'))
+ return obj
+
+
+class DataWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="Data":
+ return True
+ if classname=="DataContainer":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Data object
+ """
+ # Create a data hierarchy of the
+ elem = ElementTree.Element(obj.get_ref())
+ if hasattr(obj,'get_value') and obj.get_value() and not obj.get_map():
+ elem.text = obj.get_value()
+ elif hasattr(obj,'get_map') and obj.get_map():
+ elem.set('map', obj.get_map())
+ if hasattr(obj,'template') and obj.template == True:
+ elem.set('template','true')
+ if hasattr(obj,'policy') and obj.policy != '':
+ elem.set('extensionPolicy',obj.policy)
+ for child in obj._objects():
+ writer = DataWriter()
+ childelem = writer.dumps(child)
+ if childelem != None:
+ elem.append(childelem)
+ return elem
+
+
+class DataReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="data":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+
+ (namespace,elemname) = get_elemname(elem.tag)
+ obj = api.DataContainer(elemname, container=True)
+ for elem in elem.getchildren():
+ try:
+ reader = ElemReader(attr='data')
+ childobj = reader.loads(elem)
+ obj.add(childobj)
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return obj
+
+
+class ViewWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="View" or \
+ classname=="ConfmlView":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ elem = ElementTree.Element('view',
+ {'id' : obj.get_ref(),
+ 'name' : obj.get_name()})
+ for child in obj._objects():
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = child._get_mapper('confml').map_object(child)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ childelem = writer.dumps(child)
+ if childelem != None:
+ elem.append(childelem)
+ return elem
+
+
+class ViewReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="view":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ vid = elem.get('id')
+ name = elem.get('name')
+ view = model.ConfmlView(name, id=vid)
+ for elem in elem.getchildren():
+ # At the moment we ignore the namespace of elements
+ (namespace,elemname) = get_elemname(elem.tag)
+ try:
+ reader = get_reader_for_elem(elemname)
+ obj = reader.loads(elem)
+ view.add(obj)
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return view
+
+
+class GroupWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="Group" or classname=="ConfmlGroup":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ elem = ElementTree.Element('group',
+ {'name' : obj.get_name()})
+ for child in obj._objects():
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = child._get_mapper('confml').map_object(child)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ childelem = writer.dumps(child)
+ if childelem != None:
+ elem.append(childelem)
+ return elem
+
+
+class GroupReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=='group':
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ gname = elem.get('name')
+ gref = utils.resourceref.to_dref(gname).replace('.','_')
+ group = model.ConfmlGroup(gref, name=gname)
+ for elem in elem.getchildren():
+ # At the moment we ignore the namespace of elements
+ (namespace,elemname) = get_elemname(elem.tag)
+ try:
+ reader = get_reader_for_elem(elemname, 'group')
+ obj = reader.loads(elem)
+ if obj != None:
+ group.add(obj)
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return group
+
+
+class GroupSettingWriter(ConfmlWriter):
+ """
+ """
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="FeatureLink":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ ref = obj.fqr.replace('.','/')
+ elem = ElementTree.Element('setting',
+ {'ref' : ref})
+ return elem
+
+class GroupSettingReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=='setting' and parent=='group':
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ ref = elem.get('ref') or ''
+ ref = ref.replace('/','.')
+ return api.FeatureLink(ref)
+
+
+
+class ConfmlSettingWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlSetting" or \
+ classname=="ConfmlStringSetting" or \
+ classname=="ConfmlIntSetting" or \
+ classname=="ConfmlRealSetting" or \
+ classname=="ConfmlBooleanSetting" or \
+ classname=="ConfmlSelectionSetting" or \
+ classname=="ConfmlMultiSelectionSetting" or \
+ classname=="ConfmlDateSetting" or \
+ classname=="ConfmlTimeSetting" or \
+ classname=="ConfmlDateTimeSetting" or \
+ classname=="ConfmlDurationSetting" or \
+ classname=="ConfmlFileSetting" or \
+ classname=="ConfmlFolderSetting" or \
+ classname=="FeatureSequence" or \
+ classname=="ConfmlSequenceSetting":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ elem = ElementTree.Element('setting',
+ {'ref' : obj.get_ref(),
+ 'name' : obj.get_name()})
+ if obj.type:
+ elem.set('type', obj.get_type())
+ if hasattr(obj,'minOccurs'):
+ elem.set('minOccurs', str(obj.minOccurs))
+ if hasattr(obj,'maxOccurs'):
+ elem.set('maxOccurs', str(obj.maxOccurs))
+ if hasattr(obj,'readOnly') and obj.readOnly != None:
+ elem.set('readOnly', str(obj.readOnly).lower())
+ if hasattr(obj,'required') and obj.required != None:
+ elem.set('required', str(obj.required).lower())
+ if hasattr(obj,'constraint') and obj.constraint != None:
+ elem.set('constraint', obj.constraint)
+ if hasattr(obj,'relevant') and obj.relevant != None:
+ elem.set('relevant', obj.relevant)
+ if hasattr(obj,'mapKey') and obj.mapKey is not None:
+ elem.set('mapKey', str(obj.mapKey))
+ if hasattr(obj,'mapValue') and obj.mapValue is not None:
+ elem.set('mapValue', str(obj.mapValue))
+
+ for child in obj._objects():
+ """ Make sure that the object is mapped to an object in this model """
+ mobj = child._get_mapper('confml').map_object(child)
+ writer = get_writer_for_class(mobj.__class__.__name__)
+ childelem = writer.dumps(child)
+ if childelem != None:
+ elem.append(childelem)
+ return elem
+
+
+class ConfmlSettingReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if parent and not (parent=='feature' or parent=='setting'):
+ return False
+ if elemname=='setting':
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ typedef = elem.get('type')
+ if typedef == 'sequence':
+ map_key = elem.get('mapKey')
+ map_value = elem.get('mapValue')
+ feature = model.ConfmlSequenceSetting(elem.get('ref'), mapKey=map_key, mapValue=map_value)
+ elif typedef == 'int':
+ feature = model.ConfmlIntSetting(elem.get('ref'))
+ elif typedef == 'boolean':
+ feature = model.ConfmlBooleanSetting(elem.get('ref'))
+ elif typedef == 'selection':
+ feature = model.ConfmlSelectionSetting(elem.get('ref'))
+ elif typedef == 'multiSelection':
+ feature = model.ConfmlMultiSelectionSetting(elem.get('ref'))
+ elif typedef == 'string':
+ feature = model.ConfmlStringSetting(elem.get('ref'))
+ elif typedef == 'real':
+ feature = model.ConfmlRealSetting(elem.get('ref'))
+ elif typedef == 'file':
+ feature = model.ConfmlFileSetting(elem.get('ref'))
+ elif typedef == 'folder':
+ feature = model.ConfmlFolderSetting(elem.get('ref'))
+ elif typedef == 'date':
+ feature = model.ConfmlDateSetting(elem.get('ref'))
+ elif typedef == 'time':
+ feature = model.ConfmlTimeSetting(elem.get('ref'))
+ elif typedef == 'dateTime':
+ feature = model.ConfmlDateTimeSetting(elem.get('ref'))
+ elif typedef == 'duration':
+ feature = model.ConfmlDurationSetting(elem.get('ref'))
+
+
+ else:
+ # Handle the default setting as int type
+ feature = model.ConfmlSetting(elem.get('ref'), type=None)
+
+ if elem.get('name'):
+ feature.set_name(elem.get('name'))
+ if elem.get('minOccurs'):
+ feature.minOccurs = int(elem.get('minOccurs'))
+ if elem.get('maxOccurs'):
+ feature.maxOccurs = int(elem.get('maxOccurs'))
+ if elem.get('readOnly'):
+ feature.readOnly = elem.get('readOnly') == 'true' or False
+ if elem.get('required'):
+ feature.required = elem.get('required') == 'true' or False
+ if elem.get('constraint'):
+ feature.constraint = elem.get('constraint')
+ if elem.get('relevant'):
+ feature.relevant = elem.get('relevant')
+
+ for elem in elem.getchildren():
+ # At the moment we ignore the namespace of elements
+ (namespace,elemname) = get_elemname(elem.tag)
+ try:
+ reader = get_reader_for_elem(elemname)
+ obj = reader.loads(elem)
+ if obj != None:
+ feature.add(obj,container.APPEND)
+ else:
+ logging.getLogger('cone').warning("Invalid child %s in %s" % (elem,feature.name))
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return feature
+
+
+class ConfmlLocalPathWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlLocalPath":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The ConfmlLocalPath object
+ """
+ elem = ElementTree.Element('localPath')
+ if obj.readOnly:
+ elem.set('readOnly', unicode(obj.readOnly))
+ return elem
+
+
+class ConfmlLocalPathReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="localPath":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ return model.ConfmlLocalPath(readOnly=elem.get('readOnly'))
+
+
+class ConfmlTargetPathWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlTargetPath":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The ConfmlLocalPath object
+ """
+ elem = ElementTree.Element('targetPath')
+ if obj.readOnly:
+ elem.set('readOnly', unicode(obj.readOnly))
+ return elem
+
+
+class ConfmlTargetPathReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="targetPath":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ return model.ConfmlTargetPath(readOnly=elem.get('readOnly'))
+
+
+class DummyWriter(ConfmlWriter):
+ """
+ Dummy writer is executed on ConE model elements that are not supposed to go to the confml file
+ """
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="_FeatureProxy":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ return None
+
+
+
+class RfsReader(ConfmlReader):
+ """
+ """
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="rfs":
+ return True
+ else:
+ return False
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+
+ (namespace,elemname) = get_elemname(elem.tag)
+ obj = api.DataContainer(elemname, container=True)
+ for elem in elem.getchildren():
+ try:
+ reader = ElemReader(attr='rfs')
+ childobj = reader.loads(elem)
+ obj.add(childobj)
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return obj
+
+class ElemReader(ConfmlReader):
+ def __init__(self, **kwargs):
+ self.template = kwargs.get('template',False)
+ self.attr = kwargs.get('attr',None)
+ self.args = kwargs
+
+ def loads(self, elem):
+ """
+ @param elem: The xml include elem
+ """
+ (namespace,elemname) = get_elemname(elem.tag)
+ datavalue = None
+ if len(list(elem)) == 0:
+ datavalue = elem.text
+ datatemplate = elem.get('template') == 'true' or self.template
+ dataextensionpolicy = elem.get('extensionPolicy') or ''
+ datamap = elem.get('map')
+ obj = api.Data(ref=elemname,value=datavalue, template=datatemplate, attr=self.attr,policy=dataextensionpolicy,map=datamap)
+ for elem in elem.getchildren():
+ try:
+ reader = ElemReader(**self.args)
+ childobj = reader.loads(elem)
+ obj.add(childobj)
+ except exceptions.ConePersistenceError,e:
+ logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+ continue
+ return obj
+
+namespace_pattern = re.compile("{(.*)}(.*)")
+nonamespace_pattern = re.compile("(.*)")
+
+def get_elemname(tag):
+
+ ns = namespace_pattern.match(tag)
+ nn = nonamespace_pattern.match(tag)
+ if ns:
+ namespace = ns.group(1)
+ elemname = ns.group(2)
+ return (namespace,elemname)
+ elif nn:
+ namespace = ""
+ elemname = nn.group(1)
+ return (namespace,elemname)
+ else:
+ raise exceptions.ParseError("Could not parse tag %s" % tag)
+
+
+def get_reader_for_elem(elemname, parent=None):
+ for reader in ConfmlReader.__subclasses__():
+ if reader.supported_elem(elemname,parent):
+ return reader()
+ raise exceptions.ConePersistenceError("No reader for given elem %s under %s found!" % (elemname, parent))
+
+def get_writer_for_class(classname):
+ for writer in ConfmlWriter.__subclasses__():
+ if writer.supported_class(classname):
+ return writer ()
+ raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+if SOURCE_ROOT not in sys.path:
+ sys.path.insert(0, SOURCE_ROOT)
+
+# Find all unittest_*.py files in this folder
+import re
+__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
+# Strip .py endings
+__all__ = map(lambda name: name[:-3], __all__)
+
+def collect_suite():
+ sys.path.insert(0, ROOT_PATH)
+ try:
+ suite = unittest.TestSuite()
+ for test_module in __all__:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+ finally:
+ del sys.path[0]
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_2DigitDialing.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_2DigitDialing.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ 2 Digit Dialing.
+
+ 2 Dialing. Default is disabled
+
+
+
+
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_ActiveIdleNotifiers.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_ActiveIdleNotifiers.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+
+
+ Notification components: missed calls, new messages (device inbox), and new voice messages are located on one row of the device. It is possible to configure the notifiers on/off separately. If a notification component is turned off, the notifications are shown as traditional pop-up notifications.
+
+ Up to two different e-mail accounts for each mode can be configured to be visible on the Home screen. It is not possible to customize e-mail notifiers as they are only available when the e-mail account is first activated.
+
+
+ Calendar and To-do components provide dynamically updated information from Calendar entries and ToDo notes. If there is no data to show, "No calendar events for today" note is visible on the Home screen view.
+
+
+ The Music Player component shows the music tracks that are being played by the Music Player. If there is no data to show, this UI area is empty.
+
+
+ The Visual radio plug-in shows the name or frequency of the radio channel that is being played by Visual radio in the background. The icon also shows whether Visual radio service is available for the current channel.
+
+
+ This component shows dynamically updated information about available WLAN networks and shortcut to WLAN wizard that enables selecting WLAN network and defining access point for it. If scanning is set to off, there is 'WLAN scanning off' in Home screen view.
+
+
+ This component shows dynamically updated information about available WLAN networks and shortcut to WLAN wizard that enables selecting WLAN network and defining access point for it. If scanning is set to off, there is 'WLAN scanning off' in Home screen view.
+
+
+ This plug-in provides easy access to Voice over IP settings wizard, providing options to launch Voice over IP setup wizard or hide the plug-in from the Home screen.
+
+
+ The Mobile search plug-in allows the user to initiate a search for content in the device or in the Internet directly from Home screen. User can click on the plug-in and write the search term.
+
+
+ The SIM Application Toolkit shows messages from an application residing on the SIM card.
+
+
+
+
+true
+true
+true
+true
+true
+true
+true
+true
+true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_ActiveIdleOther.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_ActiveIdleOther.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+ Easy Dialing allows user to start dialling from Home Screen to a contact without first starting Phonebook application. The name input is predictive (subject to restrictions by input language), and the contacts are matched so that each character only requires one key press. Typing more narrows down the options. User is able to use the number that was just typed, or select one of the name matches.
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_AppShell323.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_AppShell323.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+ Application Shell customization.
+
+ Folder containing Application Shell configuration files: appshelldata.xml, appshelldata.dtd, appshellapplications.properties
+
+
+
+
+
+
+UI/Application Menu
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_CPHSALS.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_CPHSALS.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ CPHS is an extension to the GSM specification that adds several convenience and usability enhancements to the way GSM phones and SIM cards operate. Examples of CPHS enhancements include single-key access to a standard voicemail number stored on the SIM, and a message-waiting indicator to alert users to new voicemail messages. CPHS also provides carriers with greater control and flexibility over the carrier name that is displayed on the phone. CPHS also includes the ability to control certain network-based features from the phone interface, including call forwarding, call waiting, and caller-ID. CPHS is not an official part of the GSM specification. It was developed by the PCN Association rather than the GSM Association. Nonetheless, CPHS has been popular among carriers. Many European and American GSM carriers require it, and so newer GSM phones from most major manufacturers include CPHS functionality.
+
+ If ALS is set as ON, the functionality of toggling from General to Silent profile by long press # key will be disabled. CPHS and ALS can be set ON and OFF in the customer variants of the standard transceiver. CPHS and ALS can never be both set ON at the same time.
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_CellInfoDisplay.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_CellInfoDisplay.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ Cell Info Display Setting (Cell Broadcast Reception)
+
+ Cell Info Display Setting (Cell Broadcast Reception). "On" when checked. Cell info display is "Off" by default in the standard transceiver. This setting is set "On" by default for countries in which the GSM regulatory authority requires it.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_Content.confml
Binary file configurationengine/source/cone/confml/tests/data/CVC_Content.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_CustomerMenu.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_CustomerMenu.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+
+
+ Often referred to as the Operator Menu, the Customer Menu is an application that launches the browser as an embedded application with a predefined URL as parameter. The URL defines the xHTML Startup page that is shown when the Customer Menu application is launched, for example www.customername.com/index.html. The URL also defines the customer domain URL path, for example www.customername.com/. All user-browsed xHTML pages belonging to that path are automatically stored in the Customer Menu cache.The Customer Menu application can be configured as a shortcut just like any other application. In Main menu, the Customer Menu is placed by default to 11th position. When the Customer Menu is enabled, Help moves from position 11 to 12 and Apps moves from 12 to 13, which is not visible until the user scrolls the menu cursor.
+
+ Customer menu icon that will be present in Application Grid. Size: 65 x 65 pixels. Format: SVGT (preferred) or BMP. Color depth: 24 bit
+
+
+
+
+ Customer menu bitmask when using BMP menu icon. Size: 65 x 65 pixels. Format: BMP. Color depth: 8 bit
+
+
+
+
+ The text caption for Customer Menu icon
+
+
+ Target URL for Operator Menu. The URL defines the xHTML Start-up page that will be shown when the Customer Menu application is launched (e.g. “www.customername.com/index.htmâ€). The URL also defines the customer domain URL path (e.g. “www.customername.comâ€).
+
+
+ Data stored in the Customer Menu cache is preserved in the device memory and can be accessed even after the Browser session is ended and through power cycles of the device. File format: xHTML files. Customers provide the xHTML pages to be pre-installed in the Customer Menu Cache.The max. amount of data that can be stored in the Customer Menu cache is 300 KB
+
+
+
+
+ In “mm/yyyy†format. Customers define the expiration date of the xHTML page(s). After that date, the cache content will no longer be used and Operator icon will launch URL instead.
+
+
+
+
+
+UI/Customer Menu/Cache
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_InstantMessaging.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_InstantMessaging.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,74 @@
+
+
+
+ IM (Instant Messaging) settings
+
+ Server name. Max 30 chars.
+
+
+ Max 100 chars.
+
+
+ Max 50 chars.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Alert tone for Instant Messaging.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_NokiaPCInternetAccess.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_NokiaPCInternetAccess.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+
+
+Customizations of PC application "Nokia PC Internet Access"
+
+ Customer logo file. Format: Portable Network Graphics with transparent background. Size 280x40.
+
+
+
+
+ NPCIA autolaunches the default web browser of the PC. Default starting page of the browser can be set through NPCIA (when browser is launched by NPCIA)
+
+
+ Located in in NPCIAs’ ‘Settings’ view. Can be phone number and/or link to operator webpage.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_OperatorLogo.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_OperatorLogo.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+The Nokia E75 supports color logos in addition to the traditional black and white customer logos. Customer logos may be predefined in the default settings for the device or downloaded by the user. The customer logo is stored together with the MNC and MCC info of the home network in the device and will be displayed when the user is in the home network. The customer logo replaces the standard customer name.
+
+ Operator logo file. Format: BMP or SVG. Maximum size 134x33 pixels. Name must be Logo_MCC_MNC_PROG.svg or Logo_MCC_MNC_PROG.bmp, where MCC and MNC are mobile country code and mobile network code.
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_Preinstalled.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_Preinstalled.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,167 @@
+
+
+ Customer-defined pre-installed content. Please note that the total size of the User Data Area content size must not exceed 5 Mbytes.
+
+
+ Max 6 mms, max size 35K. Binary format (encoding according to MMS encapsulation specification)
+
+ Pre-Installed MMS
+
+
+
+
+
+
+
+ Pre-Installed Images. Size up to 5MP (2560x1920 pixels), format JPEG. No EXIF data allowed
+
+
+
+
+
+
+ Pre-Installed Streaming links. Format is .ram file.
+
+
+
+
+
+ Pre-Installed Music Clips.
+
+
+
+
+
+ Pre-Installed Video Clips.
+
+
+
+
+
+ Default Ringtone in General Profile. Any supported media file.
+
+
+
+
+
+
+
+ Default ringtone for incoming message event in General Profile. Any supported media file.
+
+
+
+
+
+ Default ringtone for video call event in General Profile. Any supported media file.
+
+
+
+ Pre-Installed Themes. Format is Theme project archive zip file with extesion .tpf, containing the theme project and main .tdf file.
+
+
+
+
+
+ Complementary applications pre-Installed to device ROM. Will NOT be uninstallable by end-users. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+
+
+
+ Complementary applications pre-Installed to device ROM. Will NOT be uninstallable by end-users. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+
+
+
+ Complementary applications pre-loaded to device. Offerecd for installation to the end-user. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+
+
+
+ Symbian certificates for trusted software installations.
+
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+
+ Allows installation of native Symbian OS applications (on/off)
+
+
+ Allows to validate OCSP revocation responses (on/off)
+
+
+
+
+
+ Java MIDP certificates for trusted software installations.
+
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+
+ Trusted application domain: Customer or Third-party.
+
+
+
+
+
+
+ Certificates for Internet services: SSL/TLS (HTTPS,SecureIMAP, etc.) connections.
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+ Allows to validate OCSP revocation responses (on/off)
+
+
+
+
+
+
+
+
+
+
+
+ Media/Images
+
+
+
+ Streaming Links
+
+
+
+ Media/Music
+
+
+
+ Media/Videos
+
+
+
+ UI/Themes
+
+
+
+ Applications/Pre-installed to UDA
+
+
+
+ Applications/Pre-installed to MMC
+
+
+
+ Applications/Bundled
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_RightSoftkey.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_RightSoftkey.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+ The right soft key (RSK) in idle mode can be configured to launch a customer defined application or URL. The RSK label can be branded with a graphic only if it is a URL. The left soft key (LSK) is always a text string and is not customizable. The end user is able to personalize both the left and right soft keys.
+
+ Right Softkey Customization
+
+
+ Right Softkey caption text (if RSK is not customized as image). 12 characters max (5 for Chinese variants).
+
+
+ Size: 115 x 22 pixels Format: SVGT (preferred) or BMP
+
+
+
+
+ Right softkey BMP mask. Applicable only if BMP format is used.
+
+
+
+
+ Right Softkey target URL (if target is defined as a web site).
+
+
+ Right Softkey target Application UID (if target is an application). Format is a hexadecimal number (0x00000000).
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_StartupShutdownAnimations.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_StartupShutdownAnimations.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+
+
+ Startup animation. The customer specific startup element can contain either a still image or an animation with or without a customer specified tone.
+
+ Display time for still image is max 3 seconds, for animation 2.5 max seconds.
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+
+
+ Shutdown animation. The customer specific shutdown element can contain either a still image or an animation with or without a customer specified tone.
+
+ Display time for still image is max 3 seconds, for animation 2.5 max seconds.
+
+
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+
+ 3000
+
+
+
+ UI/Start-up Animation
+
+
+
+
+ 3000
+
+
+
+
+
+ UI/Shutdown Animation
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_Streaming.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_Streaming.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,123 @@
+
+
+ Streaming Settings
+
+ Use proxy for streaming
+
+
+
+
+ Programmed (max.length 1000 characters)
+
+
+ Programmed (1-9999)
+
+
+ Programmed (max.length 100 characters)
+
+
+ Limit for online time spent in streaming
+
+
+
+
+ User-selectable value for online streaming time (if limiting is enabled)
+ (1 – 30 minutes)
+
+
+ 1024 (equal or smaller than Highest UDP port) (default 6970)
+
+
+ 65535 (equal or bigger than Lowest UDP port)(default 32000)
+
+
+ GPRS bandwidth limit for streaming
+
+
+
+
+
+
+
+
+ User defined (5 – 99.99 kbps)
+
+
+ EGPRS bandwidth limit for streaming
+
+
+
+
+
+
+
+ User defined (5 – 199.99 kbps)
+
+
+ UMTS bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+ User defined (5 – 999.99 kbps)
+
+
+ WLAN bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User defined (kbps)
+
+
+ HSDPA bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+ User defined (5 – 3999.99 kbps)
+
+
+
+
+ No
+
+ 554
+
+ Unlimited
+ 1
+ 6970
+ 32000
+ 40
+ 5
+ 89
+ 5
+ 384
+ 5
+ 1430
+ 5
+ user
+ 5
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_SyncML.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_SyncML.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,161 @@
+
+
+ SyncML Settings.
+
+ Maximum length 50 characters.
+
+
+ 1.1, 1.2 (default)
+
+
+
+
+ Server ID
+
+
+ Data bearer for server connection
+
+
+
+
+
+ Access point to use for server connetion
+
+
+
+
+ Maximum length 150 characters.
+
+
+ 80 (default), 1-65535
+
+
+ Server account: username
+
+
+ Server account: password
+
+
+ Policy for sync requests
+
+
+
+
+
+ Username for Access Point connection
+
+
+ Password for Access Point connection
+
+
+ Type of syncronization
+
+
+
+
+
+
+
+
+
+ Include Contacts in Sync ON/OFF
+
+
+
+ Include Calendar in Sync ON/OFF
+
+
+
+ Include Notes in Sync ON/OFF
+
+
+
+ Include E-mail in Sync ON/OFF
+
+
+
+ Include Music in Sync ON/OFF
+
+
+
+ Include MSyncService in Sync ON/OFF
+
+
+
+ Include Images in Sync ON/OFF
+
+
+
+ Include MMS in Sync ON/OFF
+
+
+
+ Include Video in Sync ON/OFF
+
+
+
+ Include SMS in Sync ON/OFF
+
+
+
+ Include Bookmarks in Sync ON/OFF
+
+
+
+
+
+
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+
+
+
+80
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_ThemeWallpaperScreensaver.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_ThemeWallpaperScreensaver.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,41 @@
+
+
+
+ Default Theme to be set on device. Select from the set of pre-installed themes.
+
+ Default Theme to be set on device. Select from the set of pre-installed themes.
+
+
+
+
+
+
+ Default wallpaper
+
+ Size: 240X234 pixels Format: SVGT (preferred) or BMP. 24 bit. The end user can select to change this to either a different single image or select multiple images to run in a wallpaper slide show.
+
+
+
+
+
+
+ Screensaver
+
+ Screensaver file. Format is animated GIF.
+
+
+
+
+ Duration the animation will run before reverting to default screensaver in minutes. Min 1 minute, max 30 minutes.
+
+
+ Duration of display lights being turned on while the animation runs in seconds. 0 = no lights, max 30 seconds.
+
+
+
+
+3
+15
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_VoiceMailbox.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_VoiceMailbox.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ The device number of the customer’s voice mailbox may be programmed into the device during production or in service. Voice mailbox feature may be activated in two different ways: CSP (Customer Service Profile) support is enabled in product profile AND voice mailbox numbers can be found from customer’s SIM card
+
+ Maximum allowed length is 50 characters.
+
+
+ Maximum allowed length is 50 characters.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/CVC_ZeroPlusSend.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/CVC_ZeroPlusSend.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ 0 + SEND is used in the US as access number to national operator assistance both in landline and wireless networks.
+
+ 0 + SEND is used in the US as access number to national operator assistance both in landline and wireless networks. Default is off.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/accessoryserver.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/accessoryserver.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,97 @@
+
+
+
+ featurelist
+ working
+
+
+ Central repository for accessory related UI settings.
+
+ Setting used to detect properly some connected accessories (e.g. TTY, Loopset).
+
+Phone may support some HW devices that are not properly identified when they are connected to phone. To properly identify such devices user has to tell by using appropriate user interface setting the type of connected device.
+
+
+ Lights setting for wired headset mode. User may force lights on when wired headset is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+ Lights setting for wireless headset mode. User may force lights on when wireless headset is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+ Lights setting for wired car kit mode. User may force lights on when wired car kit is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+ Lights setting for wireless car kit mode. User may force lights on when wireless car kit is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+ Lights setting for text device mode. User may force lights on when text device is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+ Lights setting for loopset. User may force lights on when loopset is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+ Lights setting for music stand. User may force lights on when music stand is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+ Lights setting for synchronization stand. User may force lights on when synchronization stand is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+
+
+
+
+
+ 4
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/booleans.confml
Binary file configurationengine/source/cone/confml/tests/data/booleans.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/commsdatcreator.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/commsdatcreator.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1667 @@
+
+
+ Used to configure whether CommsDat generation from these settings is enabled.
+
+ This is the master switch that determines whether CommsDat is created in the first boot
+ of the device based on Configuration Tool output. Set this to Yes if you are creating variant
+ and need to configure anything under Default CommsDat settings.
+
+
+
+
+ Read-only flag that indicates the CommsDatCreator start-up status in runtime.
+
+
+
+
+ Global networking related settings not tied to individual connection methods.
+
+
+
+ GPRS attach mode (attach when needed/when available).
+
+
+
+
+
+
+ Default GPRS access point. Used when the phone is used as a modem for a PC.
+ The corresponding UI setting is Connection-Packet data-Access point.
+
+
+
+
+ Default icon for destination networks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default priority for LAN bearer type.
+
+
+
+
+ Default priority for WLAN bearer type.
+
+
+
+
+ Default priority for PAN bearer type.
+
+
+
+
+ Default priority for outgoing GPRS bearer type.
+
+
+
+
+ Default priority for incoming GPRS bearer type.
+
+
+
+
+ Default priority for CDMA 2000 bearer type.
+
+
+
+
+ Default priority for outgoing dial bearer type.
+
+
+
+
+ Default priority for incoming dial bearer type.
+
+
+
+
+ Default priority for VPN bearer type.
+
+
+
+
+ Default priority for MIP bearer type.
+
+
+
+
+ Default UI priority of LAN connection.
+
+
+
+
+ Default UI priority for WLAN bearer type.
+
+
+
+
+ Default UI priority for PAN bearer type.
+
+
+
+
+ Default UI priority for outgoing GPRS bearer type.
+
+
+
+
+ Default UI priority for incoming GPRS bearer type.
+
+
+
+
+ Default UI priority for CDMA 2000 bearer type.
+
+
+
+
+ Default UI priority for outgoing dial bearer type.
+
+
+
+
+ Default UI priority for incoming dial bearer type.
+
+
+
+
+ Default UI priority for VPN bearer type.
+
+
+
+
+ Default UI priority for MIP bearer type.
+
+
+
+
+ Specifies how the applications' default connection is specified.
+
+
+
+
+
+
+
+
+ The name of the default connection (connection method or destination network).
+ Default connection type parameter needs to be set accordingly.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when session has closed. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when socket has closed. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ How often WLAN networks are scanned when idle.
+
+
+
+
+
+
+
+
+ Defines whether default values are being used for the advanced WLAN settings (recommended).
+
+
+
+
+ Defines how many times packets bigger than RTS Threshold are been resent.
+
+
+ Defines how many times packets smaller than RTS Threshold are been resent.
+
+
+ Minimum size of a packet for which CTS/RTS handshake has been used.
+
+
+ Transmission power level in use. In mWs. 4, 10 or 100 mW.
+
+
+
+
+
+ Defines whether the CCX radio measurements are allowed.
+
+
+
+
+ Defines whether power saving methods are active. Disabling WLAN
+ power save might increase interoperability but will dramatically shorten battery life.
+
+
+
+
+
+ GPRS connection method (CM) definitions
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Addressing that the network uses.
+
+
+
+
+ The access point name for this GPRS connection
+
+
+ User name
+
+
+ Prompt password at connection time.
+
+
+
+
+ Password.
+
+
+ Password authentication method.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method. In URL format.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Allow EDGE usage.
+
+
+
+
+ Specifies the service provider type. Used when filtering connection methods for certain purpose.
+
+
+
+
+
+
+
+ WLAN connection method (CM) definitions
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Service set identifier (SSID) of the primary WLAN network.
+
+
+ Start page of the connection method. In URL format.
+
+
+ Determines the network infrastructure.
+ If there is a WLAN access point in the network then this should be Infrastructure.
+
+
+
+
+ Security mode of the WLAN network.
+
+
+
+
+
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ The gateway IP address.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Network mask. Typically allocated automatically in which case this should be empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Defines whether the SSID should be actively scanned.
+ This is needed if the SSID is hidden (not broadcasted by the AP)
+
+
+
+
+
+ 802.11 Channel ID (1-14). Used only when connecting/setting up adhoc network.
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Index of default WEP key. Used only when security mode is WEP.
+
+
+
+
+
+
+ WEP authentication mode. Only used when security mode is WEP.
+
+
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WPA/WPA2 pre-shared key in plain text. ASCII character set values between 32-126 must be used. Minimum length is 8 characters and maximum 63.
+ You need to also define the WPA pre-shared key length field accordingly
+
+
+ Specifies that when the security mode is WPA or WPA2 if the PSK mode is enabled.
+ If this is off then EAP mode is used and the list of EAPs needs to be defined.
+
+
+
+
+ The length of the specified pre-shared key (in WPA pre-shared key field)
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in use. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM the string needs to be "+018".
+ The list is in priority order, highest priority first.
+
+
+
+ The username used with EAP-GTC.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with EAP-GTC.
+
+
+
+
+
+ The username used with EAP-TLS.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ Defines which EAP tunneling method is used with EAP-TLS.
+
+
+
+
+
+
+ The username used with EAP-LEAP.
+
+
+ The password used with EAP-LEAP.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ The username used with EAP-SIM.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ Defines which EAP tunneling method is used with EAP-SIM.
+
+
+
+
+
+
+ The username used with EAP-TTLS.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TTLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-TTLS. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with EAP-AKA.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with EAP-AKA.
+
+
+
+
+
+
+ The username used with EAP-PEAP.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether PEAP requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ Is PEAP version 0 allowed. If in doubt enable only this one.
+
+
+
+
+ Is PEAP version 1 allowed.
+
+
+
+
+ Is PEAP version 2 allowed.
+
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-PEAP. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with EAP-MSCHAPv2.
+
+
+ The password used with EAP-MSCHAPv2.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ Defines which EAP tunneling method is used with EAP-MSCHAPv2.
+
+
+
+
+
+ The username used with EAP-FAST.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TTLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-FAST. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ EAP-FAST authenticated provisioning mode allowed
+
+
+
+
+ EAP-FAST unauthenticated provisioning mode allowed
+
+
+
+
+ EAP-FAST warn ADHP no PAC
+
+
+
+
+ EAP-FAST warn ADHP no matching PAC
+
+
+
+
+ EAP-FAST warn not default server
+
+
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with MSCHAPv2.
+
+
+ The password used with MSCHAPv2.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with MSCHAPv2. Needs to be EAP-TTLS.
+
+
+
+
+
+ Circuit-Switched Data connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Username for the connection.
+
+
+ Prompt password on connection set-up time.
+
+
+
+
+ Password.
+
+
+ Password authentication type.
+
+
+
+
+ WAP gateway IP.
+
+
+ Starting page.
+
+
+ WTLS security.
+
+
+
+
+ Connection type.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Default telephone number.
+
+
+ Bearer speed
+
+
+
+
+
+
+
+
+
+
+ Bearer Call Type Isdn
+
+
+
+
+
+ Is callback enabled.
+
+
+
+
+ Callback type.
+
+
+
+
+ Callback number.
+
+
+ Enable compression
+
+
+
+
+ Use login script
+
+
+
+
+ Login script
+
+
+ Modem init string
+
+
+
+
+ High-speed Circuit-Switched Data connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ User name
+
+
+ Prompt password at connection time.
+
+
+
+
+ Password.
+
+
+ Password authentication method.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Default telephone number.
+
+
+ Bearer speed
+
+
+
+
+
+
+
+
+
+
+ Bearer Call Type Isdn
+
+
+
+
+
+ Is callback enabled.
+
+
+
+
+ Callback type.
+
+
+
+
+ Callback number.
+
+
+ Enable compression
+
+
+
+
+ Use login script
+
+
+
+
+ Login script
+
+
+ Modem init string
+
+
+
+
+ LAN connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ LAN interface networks.
+
+
+ LAN interface netmask.
+
+
+ LAN IP Gateway.
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+
+
+ Virtual Private Network connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ The network connection provider IAP name.
+
+
+ Service policy.
+
+
+
+
+ Destination network (SNAP) definitions.
+
+
+ The name that is visible to the user
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Metadata that specifies a few default destination networks that applications can use
+
+
+
+
+
+
+
+ DN protection level. Destination contents mean the connection methods inside the destination and their priorities.
+
+
+
+
+
+ Is DN hidden or not.
+
+
+
+
+ Is DN hidden in CConnDlg or not
+
+
+
+
+ Is DN highlighted or not.
+
+
+
+
+ Icon to be assigned to DN.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of an embedded DN that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ Normal
+ On
+ Continuous
+ Autodetect
+ Analogue
+ Yes
+ Server Number
+ No
+ No
+
+
+
+
+ User Defined
+ 0
+ No
+ No
+ No
+ 11
+
+
+ Internet
+ 1
+ Internet
+ 2
+ No
+ No
+ Yes
+ 0
+
+
+ MMS
+ 2
+ MMS
+ 2
+ No
+ Yes
+ No
+ 2
+
+
+ Operator
+ 3
+ Operator
+ 2
+ No
+ No
+ No
+ 4
+
+
+
+ whenavailable
+ 11
+ Ask once
+
+
+ 1
+ 0
+ 100
+ 1
+ 1
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 253
+ 254
+ 9
+ 0
+ 8
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 4
+ 7
+ 2347
+ 300
+ 1
+ 300
+ -1
+ 1
+ -1
+ -1
+ 1
+ -1
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ IPv4
+ No
+ Normal
+ On
+ Continuous
+ Yes
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ No
+ Normal
+ On
+ Continuous
+ Autodetect
+ Analogue
+ Yes
+ Server Number
+ No
+ No
+
+
+
+
+ No
+ No
+ No
+ No
+ Confirm first
+ On
+ Continuous
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ Infrastructure
+ Open
+ No
+ key1
+ Shared
+ 64
+ ASCII
+ 64
+ ASCII
+ 64
+ ASCII
+ 64
+ ASCII
+ No
+ 0
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+
+
+
+ 0
+ VariantData_commsdat.xml
+
+
+
+
+ false
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/cvc_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/cvc_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/cvc_view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/cvc_view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,219 @@
+
+
+
+ Custom modeled ConfMLs for E75 customization according to E75 Customization Guidelines
+
+ Settings for standard S60 Platform applications
+
+
+ Browser (xHTML) settings
+
+
+ Calendar
+
+
+ Settings for Device Manager application.
+
+
+ Media Player
+
+
+ Voice Recorder
+
+
+ Phonebook
+
+
+ Logs
+
+
+ Camcorder
+
+
+ Clock
+
+
+ Profiles
+
+
+ Positioning
+
+
+ Instant Messaging
+
+
+
+
+ Settings for personal communication and connection methods
+
+
+ Nokia NXX has StartUp Settings application. It configures access point settings based on a SIM card�s MCC and MNC and the access point information supplied to Nokia by the network operators.
+
+
+ If the Customer specifies MMS settings (including Access points) in their variant then the transceiver will be able to receive MMS messages straight away after having been powered-up.
+
+
+ SMS Settings
+
+
+ Postcard settings
+
+
+ Customers may choose to define one set of common settings for the e-mail client in the Messaging application of the device.
+
+
+ Messaging
+
+
+ Bluetooth
+
+
+ Streaming
+
+
+
+ Mobile TV
+
+
+ Settings for voice and video mailboxes
+
+
+
+
+ System settings of S60 platform
+
+
+ Accessory Profiles
+
+
+ SyncML
+
+
+
+
+
+ Light Senso
+
+
+ Java Application Settings
+
+
+ Other
+
+
+
+
+
+
+ Telephony
+
+
+ Firmware update Over The Air
+
+
+ Keypad lock settings
+
+
+ Service Messages
+
+
+ Vibra
+
+
+ TV-out
+
+
+ Software Install
+
+
+
+ Settings for branding, user interface and look & feel
+
+
+ Often referred to as the Operator Menu, the Customer Menu is an application that launches the browser as an embedded application with a predefined URL as parameter.
+
+
+
+ The Nokia NXX supports colour logos in addition to the traditional black and white Customer logos.
+
+
+
+ Nokia NXX supports the following types of ring tones and alert tones. The Customer may select to include tones of their own in any of the listed formats. The Customer can specify one as the default ringing tone in the General profile.
+
+
+ Start-up and shutdown animations
+
+
+
+
+ Application Menu
+
+
+
+ Themes
+
+
+
+ General
+
+
+
+
+
+ Nokia PC Internet Access a.k.a. Phone a modem
+
+
+
+ Homescreen or Active Idle customizations
+
+
+
+
+
+ Applications, music, video and other files preinstalled to device
+
+
+ Customer specific Symbian and Java applications can be pre-installed to device memory (UDA).
+
+
+
+
+
+ Maximum amount of 3 Customer specific MMS messages may be pre-installed in the Device memory.
+
+
+
+ Customer specific video clips may be pre-installed in the User Data Area or Memory card. The end user is able to delete them.
+
+
+
+ Customer can pre-load Music content in the User Data Area and/or memory card. They will be seen in Nseries Music Player. The end user is able to delete them.
+
+
+
+ Customer can pre-load images in the User Data Area and/or memory card. They will be seen in Photos application. The end user is able to delete them.
+
+
+
+ Pre-installed ringtones
+
+
+
+
+
+ Pre-installed security certificates (X.509)
+
+
+
+
+
+ Pre-installed Themes
+
+
+
+ Pre-defined Streaming Links
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/facets.confml
Binary file configurationengine/source/cone/confml/tests/data/facets.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/multiselection.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/data/multiselection.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+ Folder containing content for UDA
+
+
+
+ A zip file name inside the uda content directory
+
+
+
+
+ A zip file name inside the uda content directory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "first selection" "second selection"
+
+
+ /epoc32/data/uda/common001
+
+ app1.zip
+
+
+ app2.zip
+
+
+ user_app1.zip
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/data/voicemailbox.confml
Binary file configurationengine/source/cone/confml/tests/data/voicemailbox.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/basic_setting_types_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/basic_setting_types_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,62 @@
+
+
+
+ Feature with basic setting types (ConfML v2.0)
+
+
+ A real setting
+
+
+
+ An int setting
+
+
+
+ A string setting
+
+
+
+ A boolean setting
+
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+ A multi-selection setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+ "opt 0" "opt 2" "opt 4"
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/bitmask_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/bitmask_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+
+
+
+ Feature with bitmask flags
+
+ A boolean setting for bit 0
+
+
+ A boolean setting for bit 1
+
+
+ A boolean setting for bit 2
+
+
+ A boolean setting for bit 3
+
+
+ A boolean setting for bit 4
+
+
+ A boolean setting for bit 5
+
+
+
+
+ true
+ false
+ true
+ false
+ true
+ false
+
+
+
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/config_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/config_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Version1
+ Platform1
+ Date1
+ Release1
+ Editor1
+
+Description1
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/facets.confml
Binary file configurationengine/source/cone/confml/tests/testdata/read_write/facets.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,112 @@
+
+
+
+ Feature with all supported setting types
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+ A multi-selection setting
+
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+ A multi-selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+ "opt 0" "opt 2" "opt 4"
+
+ 1.0
+ 1
+ template
+ false
+ 0
+ "opt 0"
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+ "opt 1"
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+ "opt 2"
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/feature2.confml
Binary file configurationengine/source/cone/confml/tests/testdata/read_write/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/file_folder_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/file_folder_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+
+
+
+ Feature with file and folder setting types
+
+
+
+ A folder setting
+
+
+
+
+ A file setting
+
+
+
+
+
+ default_folder
+ default_target_folder/
+
+
+ default_file.txt
+ default_target_folder/default_file_renamed.txt
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/name_id_mapping_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/name_id_mapping_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Entry 1
+ Entry 2
+ Entry 3
+
+
+
+
+
+ Entry 1 e 1
+ Entry 2 e 2
+ Entry 3 e 3
+
+
+
+
+
+ Entry 1 100
+ Entry 2 120
+ Entry 3 130
+
+
+
+
+
+
+ Entry 1 1.1
+ Entry 2 1.2
+ Entry 3 1.3
+
+
+
+
+ none
+ none
+
+
+ 0
+ 0
+
+
+ none
+ none
+
+
+ 0
+ 0
+
+
+ none
+ none
+
+
+ 0
+ 0
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/option_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/option_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ none
+ str 1
+ true
+ 1
+ 2
+ 2009-09-09
+ 07:00:00
+ 2009-09-09-12:38:00+02:00
+ PT0S
+
+
+ none
+ str 1
+ true
+ 1
+ 2
+ 2009-09-09
+ 07:00:00
+ 2009-09-09-12:38:00+02:00
+ PT0S
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/read_only_setting_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/read_only_setting_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,172 @@
+
+
+
+ Feature for testing attribute 'readOnly' in settings.
+
+
+ A real setting
+
+
+
+ An int setting
+
+
+
+ A string setting
+
+
+
+ A boolean setting
+
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+ A multi-selection setting
+
+
+
+
+
+
+
+
+
+
+ A folder setting
+
+
+
+
+
+ A file setting
+
+
+
+ A date setting
+
+
+ A time setting
+
+
+ A date-time setting
+
+
+ A duration setting
+
+
+
+ A sequence setting
+
+
+ A real sub-setting
+
+
+
+ An int sub-setting
+
+
+
+ A string sub-setting
+
+
+
+ A boolean sub-setting
+
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+ A multi-selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ A folder sub-setting
+
+
+
+
+
+ A file sub-setting
+
+
+
+ A date sub-setting
+
+
+ A time sub-setting
+
+
+ A date-time sub-setting
+
+
+ A duration sub-setting
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+ "opt 0" "opt 2" "opt 4"
+
+
+ default_folder
+ default_target_folder/
+
+
+ default_file.txt
+ default_target_folder/default_file_renamed.txt
+
+
+ 2009-02-02
+ 07:30:15
+ 2009-02-02-07:00:00
+ P5Y4M3DT12H25M15S
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+ "opt 1"
+ seq/def1_folder
+ seq/def1_file.txt
+ 2009-02-02
+ 07:30:15
+ 2009-02-02-07:00:00
+ P5Y4M3DT12H25M15S
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/redefine_in_view_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/redefine_in_view_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,39 @@
+
+
+
+
+ Description from base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ test
+ 0
+ 0
+ none
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/relevant_option_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/relevant_option_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,68 @@
+
+
+
+ Feature for testing attribute 'relevant' in options.
+
+
+ A real value used for filtering the options in NormalSelection.
+
+
+ An int value used for filtering the options in NormalSelection.
+
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Determines whether sequence items from Sequence1 are used in NameIdMappedSelection.
+
+
+ Determines whether sequence items from Sequence2 are used in NameIdMappedSelection.
+
+
+
+ A selection setting with name-ID mapped options
+
+
+
+
+
+
+
+
+ 0.5
+ 5
+ none
+
+ Sequence1 item 1
+ Sequence1 item 2
+ Sequence1 item 3
+ Sequence2 item 1
+ Sequence2 item 2
+ Sequence2 item 3
+ true
+ false
+ none
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/sequence_setting_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/sequence_setting_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,117 @@
+
+
+
+ Feature with a sequence setting (ConfML v2.0)
+
+
+ A sequence setting
+
+
+
+
+ A folder sub-setting
+
+
+
+ A real sub-setting
+
+
+
+
+
+ A file sub-setting
+
+
+
+ An int sub-setting
+
+
+
+ A string sub-setting
+
+
+
+ A boolean sub-setting
+
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+ A multi-selection sub-setting
+
+
+
+
+
+
+
+
+ A date sub-setting
+
+
+ A time sub-setting
+
+
+ A date-time sub-setting
+
+
+ A duration sub-setting
+
+
+
+
+
+
+
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+ "opt 0"
+ 2009-02-02
+ 07:30:15
+ 2009-02-02-07:00:00
+ P5Y4M3DT12H25M15S
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+ "opt 1"
+ 2009-02-02
+ 07:30:15
+ 2009-02-02-07:00:00
+ P5Y4M3DT12H25M15S
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ false
+ 1
+ "opt 2"
+ 2009-02-02
+ 07:30:15
+ 2009-02-02-07:00:00
+ P5Y4M3DT12H25M15S
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/time_types_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/time_types_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+ Feature with date-time etc. setting types
+
+ A date setting
+
+
+ A time setting
+
+
+ A date-time setting
+
+
+ A duration setting
+
+
+
+
+ 2009-02-02
+ 07:30:15
+ 2009-02-02-07:00:00
+ P5Y4M3DT12H25M15S
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/testdata/read_write/view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,81 @@
+
+
+
+ Testing view located on layer 1.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Description from view
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/unittest_confmlxml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/unittest_confmlxml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import unittest
+import string
+import sys
+import os
+import shutil
+import __init__
+
+from cone.public import api, exceptions, persistence
+from cone.storage import filestorage
+from cone.confml import persistentconfml, model, confmltree
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestConfmlXml(unittest.TestCase):
+
+ def test_namespaces(self):
+ root = confmltree.Element('root')
+ elem = confmltree.Element('{http://spam.effbot.org}egg')
+ root.append(elem)
+ elem.append(confmltree.Element('{http://spam.effbot.org}ham'))
+ elem.append(confmltree.Element('{http://test.com}foo'))
+ str = confmltree.tostring(root, {'http://spam.effbot.org': 'ham',
+ 'http://test.com': 'bar'})
+ et = confmltree.fromstring(str)
+ self.assertTrue(et)
+ self.assertEquals(str,' ')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/unittest_implml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/unittest_implml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os
+import __init__
+from cone.public.exceptions import NotSupportedException
+
+from cone.confml import implml
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestImplementation(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_create_implml(self):
+ imp = implml.Implml('test.txt',None)
+
+ def test_generate_not_supported(self):
+ try:
+ imp = implml.Implml('test.txt',None)
+ imp.generate()
+ self.fail("Implementation base class should not support generation")
+ except NotSupportedException:
+ pass
+
+# def test_list_output_files(self):
+# imp = implml.Implml('ref/test.txt',None,ROOT_PATH)
+# files = imp.list_output_files()
+# self.assertTrue(len(files)>0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/unittest_mapping.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/unittest_mapping.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,133 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import unittest
+import string
+import sys
+import os
+import shutil
+import __init__
+
+from cone.public import api, exceptions
+from cone.confml import model, mapping
+from cone.carbon import persistentjson, model as carbonmodel
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestGetMapper(unittest.TestCase):
+ def test_get_mapper(self):
+ mapper = model.get_mapper('carbon')
+ self.assertTrue(isinstance(mapper, mapping.Confml2carbon))
+
+ def test_get_mapper_from_object(self):
+ s = model.ConfmlSetting("test")
+ mapper = s._get_mapper('carbon')
+ self.assertTrue(isinstance(mapper, mapping.Confml2carbon))
+
+
+class TestCarbon2confml(unittest.TestCase):
+ def test_map_carbon_configuration(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlConfiguration("test")
+ c2 = mapper.configuration(c1)
+ c3 = c1._get_mapper('carbon').map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonConfiguration))
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonConfiguration))
+ self.assertTrue(isinstance(c3, carbonmodel.CarbonConfiguration))
+
+ def test_map_carbon_featurelist(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlConfiguration(name="test")
+ c1.meta = {}
+ c1.meta.add('type','featurelist')
+ c2 = mapper.configuration(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.FeatureList))
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.FeatureList))
+
+ def test_map_carbon_featurelist_with_features(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlConfiguration(name="test")
+ c1.add_feature(model.ConfmlFeature('Group'))
+ c1.meta = {}
+ c1.meta.add('type','featurelist')
+ c2 = mapper.configuration(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.FeatureList))
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.FeatureList))
+# self.assertEquals(c2.list_features(), ['Group'])
+
+ def test_map_carbon_configuration_with_data(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlConfiguration("test")
+ c1.name = "test.confml"
+ c1.namespace = "com.nokia"
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonConfiguration))
+ self.assertEquals(c2.name, "test.confml")
+ self.assertEquals(c2.namespace, "com.nokia")
+ self.assertEquals(c2.path, "test")
+
+ def test_map_carbon_setting_with_data(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_setting_with_desc(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlSetting("test")
+ c1.desc = 'Testing man'
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+ self.assertEquals(c2.desc, "Testing man")
+
+ def test_map_carbon_int_setting_with_data(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlIntSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonIntSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_setting_with_data(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlBooleanSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonBooleanSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_setting_with_data(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlSelectionSetting("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonSelectionSetting))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
+
+ def test_map_carbon_feature(self):
+ mapper = model.get_mapper('carbon')
+ c1 = model.ConfmlFeature("test")
+ c2 = mapper.map_object(c1)
+ self.assertTrue(isinstance(c2, carbonmodel.CarbonFeature))
+ self.assertEquals(c2.name, "test")
+ self.assertEquals(c2.ref, "test")
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/unittest_model.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/unittest_model.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,611 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import string
+import sys
+import __init__
+
+from cone.public import api, exceptions
+from cone.confml import model
+
+
+class TestConfmlMeta(unittest.TestCase):
+ def test_create_meta(self):
+ metaelem = model.ConfmlMeta()
+ self.assertTrue(metaelem)
+
+ def test_create_with_data(self):
+ prop1 = model.ConfmlMetaProperty("foo", 123)
+ prop2 = model.ConfmlMetaProperty("bar", 312)
+ prop3 = model.ConfmlMetaProperty("test", 'testing string')
+ prop4 = model.ConfmlMetaProperty("testName", 'testing string2', \
+ "http://www.nokia.com/xml/cpf-id/1", \
+ attrs={"name":"name1", "value": "value1"})
+ metaelem = model.ConfmlMeta([prop1, prop2, prop3, prop4])
+ self.assertEquals(metaelem[0].tag, "foo")
+ self.assertEquals(metaelem[0].value, 123)
+ self.assertEquals(metaelem[1].tag, "bar")
+ self.assertEquals(metaelem[1].value, 312)
+ self.assertEquals(metaelem[2].tag, "test")
+ self.assertEquals(metaelem[2].value, "testing string")
+ self.assertEquals(metaelem[3].tag, "testName")
+ self.assertEquals(metaelem[3].value, "testing string2")
+ self.assertEquals(metaelem[3].ns, "http://www.nokia.com/xml/cpf-id/1")
+
+ def test_add_data(self):
+ metaelem = model.ConfmlMeta()
+ metaelem.append(model.ConfmlMetaProperty('test', 123, "abc", attrs = {"foo":"bar", "abc":1}))
+ self.assertEquals(metaelem[0].tag, 'test')
+ self.assertEquals(metaelem[0].value, 123)
+ self.assertEquals(metaelem[0].ns, "abc")
+ self.assertEquals(metaelem[0].attrs, {"foo":"bar", "abc":1})
+
+ def test_find_data(self):
+ metaelem = model.ConfmlMeta()
+ metaelem.append(model.ConfmlMetaProperty('test', 123, "abc",\
+ attrs = {"foo":"bar", "abc":1}))
+ metaelem.append(model.ConfmlMetaProperty('abc', "efg", None,\
+ attrs = {"foo2":"bar2", "abc2":2}))
+ self.assertEquals(metaelem.find_by_tag("test"), 0)
+ self.assertEquals(metaelem.get_property_by_tag("test").tag, 'test')
+ self.assertEquals(metaelem.get_property_by_tag("test").value, 123)
+ self.assertEquals(metaelem.get("test"), 123)
+ self.assertEquals(metaelem.get("test", 'ddd'), 123)
+ # test get_value with not found elem
+ self.assertEquals(metaelem.get("notthere"), None)
+ self.assertEquals(metaelem.get("notthere", 'fooman'), 'fooman')
+ self.assertEquals(metaelem.find_by_attribute("foo2", "bar2"), 1)
+ self.assertEquals(metaelem.find_by_attribute("qwerty", ""), -1)
+
+ def test_clone_meta(self):
+ prop1 = model.ConfmlMetaProperty("foo", 123)
+ prop2 = model.ConfmlMetaProperty("bar", 312)
+ prop3 = model.ConfmlMetaProperty("test", 'testing string')
+ metaelem1 = model.ConfmlMeta([prop1, prop2, prop3])
+ metaelem2 = metaelem1.clone()
+ self.assertEquals(metaelem1, metaelem2)
+
+
+class TestConfmlDescription(unittest.TestCase):
+ def test_create_desc(self):
+ descelem1 = model.ConfmlDescription("testing")
+ descelem2 = model.ConfmlDescription()
+ descelem3 = model.ConfmlDescription()
+ descelem3.text = "changed"
+ self.assertEquals(descelem1.text, "testing")
+ self.assertEquals(descelem2.text, "")
+ self.assertEquals(descelem3.text, "changed")
+
+ def test_clone_desc(self):
+ descelem1 = model.ConfmlDescription("testing")
+ descelem2 = descelem1._clone()
+ self.assertEquals(descelem1.text, descelem2.text)
+
+class TestConfmlGroup(unittest.TestCase):
+ def test_create_group(self):
+ group1 = model.ConfmlGroup("foo")
+ self.assertEquals(group1.ref, "foo")
+ self.assertEquals(group1.icon, None)
+ self.assertEquals(group1.desc, None)
+
+ def test_group_access_icon(self):
+ group1 = model.ConfmlGroup("foo", icon='first/icon.bmp')
+ self.assertEquals(group1.icon, "first/icon.bmp")
+ group1.icon = 'foo/bar.jpg'
+ self.assertEquals(group1.icon, "foo/bar.jpg")
+ del group1.icon
+ self.assertEquals(group1.icon, None)
+
+ def test_group_access_description(self):
+ group1 = model.ConfmlGroup("foo", desc='Testing description. for this something!')
+ self.assertEquals(group1.desc, "Testing description. for this something!")
+ group1.desc = 'Something else'
+ self.assertEquals(group1.desc, "Something else")
+ del group1.desc
+ self.assertEquals(group1.icon, None)
+
+ def test_clone_group(self):
+ group1 = model.ConfmlGroup("foo")
+ group2 = group1._clone()
+ self.assertEquals(group1.ref, group2.ref)
+ self.assertEquals(group1.desc, group2.desc)
+ self.assertEquals(group1.icon, group2.icon)
+
+ group1 = model.ConfmlGroup("foo", desc='testing desc', icon='link.bmp')
+ group2 = group1._clone(recursion=True)
+ self.assertEquals(group1.ref, group2.ref)
+ self.assertEquals(group1.desc, group2.desc)
+ self.assertEquals(group1.icon, group2.icon)
+
+
+class TestConfmlSetting(unittest.TestCase):
+ def test_create_setting(self):
+ elem = model.ConfmlSetting('test')
+ self.assertTrue(elem)
+ self.assertEquals(elem.desc, None)
+ self.assertEquals(elem.readOnly, None)
+ self.assertEquals(elem.constraint, None)
+ self.assertEquals(elem.required, None)
+ self.assertEquals(elem.relevant, None)
+
+ def test_getters(self):
+ elem = model.ConfmlSetting('foo')
+ self.assertTrue(elem.get_ref(),'foo')
+ self.assertEquals(elem.get_type(),None)
+ self.assertTrue(elem.get_name(),'foo')
+
+ def test_set_type(self):
+ elem = model.ConfmlSetting('foo')
+ elem.type = 'string'
+ self.assertTrue(elem.ref,'foo')
+ self.assertTrue(elem.type,'string')
+ self.assertTrue(elem.name,'foo')
+
+ def test_setting_with_options(self):
+ elem = model.ConfmlSetting('foo',type='selection')
+ elem.create_option('foo','1')
+ elem.create_option('bar','bar')
+ elem.create_option('hou','sut')
+ self.assertTrue('1' in elem.get_valueset())
+ self.assertEquals(elem.options['1'].name, 'foo')
+ self.assertEquals(elem.options['1'].value, '1')
+ self.assertEquals(elem.options['bar'].name, 'bar')
+
+ def test_setting_create_with_nonetype(self):
+ elem = model.ConfmlSetting('foo',type=None)
+ self.assertEqual(elem.type,None)
+
+ def test_setting_with_properties(self):
+ elem = model.ConfmlSetting('foo')
+ elem.add_property(name='foo',value='bar/foo')
+ elem.add_property(name='bar',value='only/bar')
+ elem.add_property(name='testing',value='1', unit='mB')
+ self.assertEquals(elem.list_properties(), ['foo','bar','testing'])
+ self.assertEquals(elem.get_property('foo').value, 'bar/foo')
+ elem.remove_property('foo')
+ try:
+ elem.remove_property('bss')
+ self.fail('removing invalid succeeds')
+ except exceptions.NotFound:
+ pass
+ self.assertEquals(elem.list_properties(), ['bar','testing'])
+ for property_name in elem.list_properties():
+ elem.remove_property(property_name)
+ self.assertEquals(elem.list_properties(), [])
+
+
+ def test_setting_with_properties_property(self):
+ elem = model.ConfmlSetting('foo')
+ elem.add_property(name='foo',value='bar/foo')
+ elem.add_property(name='bar',value='only/bar')
+ elem.add_property(name='testing',value='1', unit='mB')
+ self.assertEquals(elem.properties['foo'].value,'bar/foo')
+ self.assertEquals(elem.properties['bar'].value,'only/bar')
+
+ def test_setting_with_readOnly_value(self):
+ elem = model.ConfmlSetting('foo', readOnly=True)
+ self.assertEquals(elem.readOnly,True)
+ elem.readOnly = False
+ self.assertEquals(elem.readOnly,False)
+
+ def test_setting_with_constaint(self):
+ elem = model.ConfmlSetting('foo', constraint=". > '1'")
+ self.assertEquals(elem.constraint,". > '1'")
+ elem.constraint = 'foobar'
+ self.assertEquals(elem.constraint,"foobar")
+
+ def test_setting_with_required_value(self):
+ elem = model.ConfmlSetting('foo', required=False)
+ self.assertEquals(elem.required,False)
+ elem = model.ConfmlSetting('foo', required=True)
+ self.assertEquals(elem.required,True)
+ elem.required = False
+ self.assertEquals(elem.required,False)
+
+ def test_setting_with_relevant_value(self):
+ elem = model.ConfmlSetting('foo', relevant='ffoo oss')
+ self.assertEquals(elem.relevant,'ffoo oss')
+ elem.relevant = ''
+ self.assertEquals(elem.relevant,'')
+
+ def test_setting_with_max_length(self):
+ elem = model.ConfmlSetting('foo', maxLength=10)
+ self.assertEquals(elem.maxLength,10)
+ elem.maxLength = 20
+ self.assertEquals(elem.maxLength,20)
+ self.assertTrue(elem._has(model.ConfmlMaxLength.refname))
+
+ def test_setting_with_min_length(self):
+ elem = model.ConfmlSetting('foo', minLength=10)
+ self.assertEquals(elem.minLength,10)
+ elem.minLength = 20
+ self.assertEquals(elem.minLength,20)
+ self.assertTrue(elem._has(model.ConfmlMinLength.refname))
+
+ def test_setting_rfs_casting(self):
+ elem = model.ConfmlSetting('foo', minLength=10)
+ self.assertEquals(elem.get_rfs_cast('true'),True)
+ self.assertEquals(elem.get_rfs_cast('false'),False)
+ self.assertEquals(elem.set_rfs_cast(True),'true')
+ self.assertEquals(elem.set_rfs_cast(False),'false')
+ self.assertEquals(elem.set_rfs_cast(1),'true')
+
+class TestConfmlSelectionSetting(unittest.TestCase):
+ def test_create_selection_setting(self):
+ elem = model.ConfmlSelectionSetting('foo')
+ self.assertTrue(elem)
+ self.assertEquals(elem.type, 'selection')
+ self.assertEquals(elem.desc, None)
+ self.assertEquals(elem.readOnly, None)
+ self.assertEquals(elem.constraint, None)
+ self.assertEquals(elem.required, None)
+ self.assertEquals(elem.relevant, None)
+
+ def test_selection_valueset(self):
+ elem = model.ConfmlSelectionSetting('foo')
+ self.assertEquals(elem.type, 'selection')
+ elem.create_option('foo', '1')
+ elem.create_option('bar', '2')
+ elem.create_option('baz', '3')
+ self.assertEquals(elem.get_valueset(), api.ValueSet(['1', '2', '3']))
+
+class TestConfmlMultiSelectionSetting(unittest.TestCase):
+ def test_create_multiselection_setting(self):
+ elem = model.ConfmlMultiSelectionSetting('mset1')
+ self.assertTrue(elem)
+ self.assertEquals(elem.type, 'multiSelection')
+ self.assertEquals(elem.desc, None)
+ self.assertEquals(elem.readOnly, None)
+ self.assertEquals(elem.constraint, None)
+ self.assertEquals(elem.required, None)
+ self.assertEquals(elem.relevant, None)
+
+ def test_multiselection_valueset(self):
+ elem = model.ConfmlMultiSelectionSetting('foo')
+ self.assertEquals(elem.type, 'multiSelection')
+ elem.create_option('foo', '1')
+ elem.create_option('bar', '2')
+ elem.create_option('baz', '3')
+ self.assertEquals(elem.get_valueset(), api.ValueSet(['1', '2', '3']))
+
+ def test_setting_value_to_multiselection(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlMultiSelectionSetting('mset2', type='multiSelection')
+ conf.add_feature(elem)
+ elem.value = "\"sel1\" \"sel2\""
+ self.assertEquals(elem.type, 'multiSelection')
+ self.assertEquals(elem.get_data_cast("\"sel1\" \"sel2\""), ["sel1", "sel2"])
+ self.assertEquals(elem.get_value(), ["sel1", "sel2"])
+
+ def test_set_data_cast(self):
+ elem = model.ConfmlMultiSelectionSetting('mset3', type='multiSelection')
+ self.assertEquals(elem.set_data_cast('"sel1" "sel2 with some spaces"'), '"sel1" "sel2 with some spaces"')
+ self.assertEquals(elem.set_data_cast(["sel1", "sel2 with some spaces"]), '"sel1" "sel2 with some spaces"')
+ self.assertEquals(elem.set_data_cast(["1", "1"]), '"1" "1"')
+ self.assertEquals(elem.set_data_cast([1, 2, 3]), '"1" "2" "3"')
+
+
+ def test_get_data_cast(self):
+ elem = model.ConfmlMultiSelectionSetting('mset3', type='multiSelection')
+ self.assertEquals(elem.get_data_cast('"sel1" "sel2 with some spaces"'), ["sel1", "sel2 with some spaces"])
+ self.assertEquals(elem.get_data_cast('"sel1" "sel2 space" "foo bar"'), ["sel1", "sel2 space", "foo bar"])
+
+ def test_setting_value_to_multiselection2(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlMultiSelectionSetting('mset3', type='multiSelection')
+ conf.add_feature(elem)
+ elem.value = '"sel1" "sel2 with some spaces"'
+ self.assertEquals(elem.type, 'multiSelection')
+ self.assertEquals(elem.get_value(), ["sel1", "sel2 with some spaces"])
+ elem.value = ["sel1", "sel2 with some spaces"]
+ self.assertEquals(elem.get_value(), ["sel1", "sel2 with some spaces"])
+
+ def test_setting_not_list_value_to_multiselection(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlMultiSelectionSetting('mset4', type='multiSelection')
+ conf.add_feature(elem)
+ self.assertRaises(ValueError, elem.set_value, "not list")
+
+ def test_setting_list_value_to_multiselection(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlMultiSelectionSetting('mset5', type='multiSelection')
+ conf.add_feature(elem)
+ elem.set_value(["li1", "li2"])
+ self.assertEquals(elem.get_value(), ["li1", "li2"])
+ self.assertEquals(elem.get_data().get_value(), '"li1" "li2"')
+
+class TestConfmlIntSetting(unittest.TestCase):
+ def test_create_setting(self):
+ elem = model.ConfmlIntSetting('test')
+ self.assertTrue(elem)
+ self.assertEquals(elem.type, 'int')
+ self.assertEquals(elem.desc, None)
+ self.assertEquals(elem.readOnly, None)
+ self.assertEquals(elem.constraint, None)
+ self.assertEquals(elem.required, None)
+ self.assertEquals(elem.relevant, None)
+
+ def test_setting_value_to_int(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlIntSetting('foo', type='int')
+ conf.add_feature(elem)
+ elem.value = 1
+ self.assertEquals(elem.value,1)
+ self.assertEquals(elem.get_original_value(),'1')
+ self.assertEquals(elem.get_data().get_value(),'1')
+
+ def test_setting_value_with_incompatible_values(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlIntSetting('foo')
+ conf.add_feature(elem)
+ try:
+ elem.value = 'hh'
+ self.fail('setting string to int succeeds')
+ except ValueError:
+ pass
+ elem.value = '1234'
+ self.assertEquals(elem.value, 1234)
+ elem.value = 0xA
+ self.assertEquals(elem.value, 10)
+ del elem.value
+ self.assertEquals(elem.value, None)
+
+ def test_setting_value_to_int(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem1 = model.ConfmlIntSetting('foo')
+ elem2 = model.ConfmlIntSetting('bar')
+ conf.add_feature(elem1)
+ conf.add_feature(elem2)
+ elem1.value = 1
+ elem2.value = 2
+ test = elem1.value + elem2.value
+ self.assertEquals(test,3)
+ elem1.value = elem1.value + elem2.value + 5
+ self.assertEquals(elem1.value,8)
+
+class TestConfmlBooleanSetting(unittest.TestCase):
+ def test_create_setting(self):
+ elem = model.ConfmlBooleanSetting('test')
+ self.assertTrue(elem)
+ self.assertEquals(elem.type, 'boolean')
+ self.assertEquals(elem.desc, None)
+ self.assertEquals(elem.readOnly, None)
+ self.assertEquals(elem.constraint, None)
+ self.assertEquals(elem.required, None)
+ self.assertEquals(elem.relevant, None)
+
+ def test_setting_value_to_int(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlBooleanSetting('foo', type='int')
+ self.assertEquals(elem.type, 'boolean')
+ conf.add_feature(elem)
+ elem.value = 1
+ # Set elem rfs value
+ elem.set_value(True, 'rfs')
+ self.assertEquals(elem.get_value('rfs'),True)
+ self.assertEquals(elem.get_original_value('rfs'),'true')
+ self.assertEquals(elem.value,1)
+ self.assertEquals(elem.get_original_value(),'true')
+ self.assertEquals(elem.get_data().get_value(),'true')
+
+ def test_setting_value_with_incompatible_values(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlBooleanSetting('foo')
+ conf.add_feature(elem)
+ elem.value = '1234'
+ self.assertEquals(elem.value, True)
+ elem.value = 0xA
+ self.assertEquals(elem.value, True)
+ elem.value = False
+ self.assertEquals(elem.value, False)
+ elem.value = ''
+ self.assertEquals(elem.value, False)
+ del elem.value
+ self.assertEquals(elem.value, None)
+
+ def test_setting_value_with_supported_values(self):
+ conf = model.ConfmlConfiguration('test.confml')
+ elem = model.ConfmlBooleanSetting('foo')
+ conf.add_feature(elem)
+ elem.value = '1'
+ self.assertEquals(elem.value, True)
+ elem.value = 'true'
+ self.assertEquals(elem.value, True)
+ elem.value = True
+ self.assertEquals(elem.value, True)
+ elem.value = '0'
+ self.assertEquals(elem.value, False)
+ elem.value = 'false'
+ self.assertEquals(elem.value, False)
+ elem.value = False
+ self.assertEquals(elem.value, False)
+ del elem.value
+ self.assertEquals(elem.value, None)
+
+class TestConfmlSequenceSetting(unittest.TestCase):
+ def test_create_setting(self):
+ elem = model.ConfmlSequenceSetting('test')
+ self.assertTrue(elem)
+ self.assertEquals(elem.desc, None)
+
+ def test_setting_with_properties_property(self):
+ elem = model.ConfmlSequenceSetting('foo')
+ elem.add_property(name='foo',value='bar/foo')
+ elem.add_property(name='bar',value='only/bar')
+ elem.add_property(name='testing',value='1', unit='mB')
+ self.assertEquals(elem.properties['foo'].value,'bar/foo')
+ self.assertEquals(elem.properties['bar'].value,'only/bar')
+
+ def test_setting_with_min_occurs(self):
+ elem = model.ConfmlSequenceSetting('foo', minOccurs=1)
+ self.assertEquals(elem.minOccurs,1)
+ elem.minOccurs = 2
+ self.assertEquals(elem.minOccurs,2)
+
+ def test_setting_with_max_occurs(self):
+ elem = model.ConfmlSequenceSetting('foo', maxOccurs=10)
+ self.assertEquals(elem.maxOccurs,10)
+ elem.maxOccurs = 20
+ self.assertEquals(elem.maxOccurs,20)
+
+ def test_create_feature_seq_with_int_bool_settings_access_feature_value_with_property(self):
+ config = api.Configuration('foo.confml')
+ fea= model.ConfmlSequenceSetting("foo")
+ fea.add_feature(model.ConfmlIntSetting('child1'))
+ fea.add_feature(model.ConfmlBooleanSetting('child2'))
+ fea.add_feature(model.ConfmlSetting('child3'))
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ foofea = dview.get_feature('foo')
+ # Test adding a data row with array
+ foofea.set_value([['1','2','3'],
+ ['4','5','6'],
+ ['7','8','9']
+ ])
+ self.assertEquals(foofea.value, [['1','2','3'],
+ ['4','5','6'],
+ ['7','8','9']
+ ])
+
+ foofea.value = [['1','2','3'],
+ ['7','8','9']
+ ]
+
+ self.assertEquals(foofea.data[0].value,['1','2','3'])
+ self.assertEquals(foofea.data[1].value,['7','8','9'])
+ self.assertEquals(foofea.data[1][1].value,'8')
+ self.assertEquals(foofea.get_value(), [['1','2','3'],
+ ['7','8','9']
+ ])
+ self.assertEquals(foofea.child1.value,['1','7'])
+
+class TestConfmlFile(unittest.TestCase):
+ def test_create_localpath_elem(self):
+ elem = model.ConfmlLocalPath()
+ self.assertTrue(elem)
+ self.assertEquals(elem.get_ref(),'localPath')
+
+ def test_create_targetpath_elem(self):
+ elem = model.ConfmlTargetPath()
+ self.assertTrue(elem)
+ self.assertEquals(elem.get_ref(),'targetPath')
+
+ def test_create_file_elem(self):
+ elem = model.ConfmlFileSetting('test')
+ self.assertTrue(elem)
+ self.assertEquals(elem.get_ref(),'test')
+ self.assertEquals(elem.list_features(), ['localPath','targetPath'])
+ self.assertEquals(elem.get_feature('localPath').fqr, 'test.localPath')
+ self.assertEquals(elem.get_feature('targetPath').fqr, 'test.targetPath')
+
+ def test_create_file_elem_and_set_value(self):
+ config = api.Configuration('test.confml')
+ elem = model.ConfmlFileSetting('test', localpath='test.txt')
+ config.add_feature(elem)
+ dview = config.get_default_view()
+ self.assertEquals(dview.list_all_features(),['test','test.localPath','test.targetPath'])
+ dview.get_feature('test.localPath').set_value('foo/test.txt')
+ dview.get_feature('test.targetPath').set_value('Z:\\test\test.txt')
+ dview.get_feature('test.localPath').set_value('now/test.txt')
+ self.assertEquals(dview.get_feature('test.localPath').get_value(),'now/test.txt')
+ self.assertEquals(len(dview.get_feature('test.localPath').get_datas()),1)
+
+ def test_clone_file_elem(self):
+ elem1 = model.ConfmlFileSetting('test')
+ elem2 = elem1._clone(recursion=True)
+
+
+class TestConfmlIcon(unittest.TestCase):
+ def test_create_icon(self):
+ icon = model.ConfmlIcon("test/foo/bar.jpg")
+ self.assertEquals(icon.href, "test/foo/bar.jpg")
+ icon.href = 'new/icon.jpg'
+ self.assertEquals(icon.href, "new/icon.jpg")
+
+ def test_clone_icon(self):
+ icon1 = model.ConfmlIcon("test/foo/bar.jpg")
+ icon2 = icon1._clone()
+ self.assertEquals(icon1.href, icon2.href)
+
+
+class TestLengths(unittest.TestCase):
+ def test_create_maxLength(self):
+ max = model.ConfmlMaxLength('100')
+ self.assertEquals(max.value, '100')
+
+ def test_create_minLength(self):
+ min = model.ConfmlMinLength('100')
+ self.assertEquals(min.value, '100')
+
+class TestConfmlFacets(unittest.TestCase):
+ def test_create_inclusive(self):
+ min = model.ConfmlMinInclusive('-10')
+ max = model.ConfmlMaxInclusive('10')
+ self.assertEquals(min.value, '-10')
+ self.assertEquals(max.value, '10')
+
+ def test_create_exclusive(self):
+ min = model.ConfmlMinExclusive('0')
+ max = model.ConfmlMaxExclusive("9")
+ self.assertEquals(min.value, '0')
+ self.assertEquals(max.value, '9')
+
+ def test_create_pattern(self):
+ pattern = model.ConfmlPattern("[a-zA-Z]")
+ self.assertEquals(pattern.value, "[a-zA-Z]")
+
+ def test_create_totalDigits(self):
+ digits = model.ConfmlTotalDigits("3")
+ self.assertEquals(digits.value, '3')
+
+class TestConfmlConfiguration(unittest.TestCase):
+ def test_create_configuration(self):
+ config = model.ConfmlConfiguration("test/foo/bar.jpg")
+ self.assertEquals(config.meta, None)
+ self.assertEquals(config.desc, None)
+ self.assertEquals(config.name, 'test__foo__bar_jpg')
+ self.assertEquals(config.ref, 'test__foo__bar_jpg')
+ self.assertEquals(config.path, 'test/foo/bar.jpg')
+
+# def test_configuration_access_meta(self):
+# config = model.ConfmlConfiguration("test/foo/bar.jpg", meta={'test':'foo','bar':' hd dd'})
+# self.assertEquals(config.meta.dict, {'test':'foo','bar':' hd dd'})
+# self.assertEquals(config.meta['test'],'foo')
+# config.meta = {'test':'123'}
+# self.assertEquals(config.meta['test'],'123')
+# del config.meta
+# self.assertEquals(config.meta, None)
+
+ def test_configuration_access_desc(self):
+ config = model.ConfmlConfiguration("test/foo/bar.jpg", desc="testing description")
+ self.assertEquals(config.desc, "testing description")
+ config.desc = 'new desc'
+ self.assertEquals(config.desc, "new desc")
+ del config.desc
+ self.assertEquals(config.desc, None)
+
+class TestConfmlProperty(unittest.TestCase):
+ def test_create_property(self):
+ property = model.ConfmlProperty(name='test',value='foo', unit='kB')
+ self.assertEquals(property.name, 'test')
+ self.assertEquals(property.value, 'foo')
+ self.assertEquals(property.unit, 'kB')
+ property.name = 'testnew'
+ property.value = 'foo faa'
+ self.assertEquals(property.name, 'testnew')
+ self.assertEquals(property.value, 'foo faa')
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/confml/tests/unittest_persistentconfml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/unittest_persistentconfml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1211 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import unittest
+import string
+import sys
+import os
+import shutil
+import __init__
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+from cone.public import api, exceptions, persistence
+from cone.storage import filestorage
+from cone.confml import persistentconfml, model
+from testautomation.base_testcase import BaseTestCase
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+testdata = os.path.join(ROOT_PATH,'data')
+
+simplerootxml = \
+'''
+
+
+
+'''
+
+newincludexml = '''
+
+
+ '''
+
+complexrootxml = '''
+
+
+
+
+
+ '''
+
+
+morestuff='''
+
+
+
+
+ Variant1 creator
+ somestorage:somelocation_123/and/path
+ proto_b2
+
+ This is a configuration for Product1 Region1 Variant1
+
+
+
+
+ '''
+
+actualconfml='''
+
+
+
+
+
+
+
+
+
+ Status pane layout setting. 0 = normal, 1 = flat, 2 = hidden
+
+
+
+
+
+
+ Often referred to as the Operator Menu, the Customer Menu is an application that launches the browser as an embedded application with a predefined URL as parameter. The URL defines the xHTML Startup page that is shown when the Customer Menu application is launched, for example www.customername.com/index.html. The URL also defines the customer domain URL path, for example www.customername.com/. All user-browsed xHTML pages belonging to that path are automatically stored in the Customer Menu cache.The Customer Menu application can be configured as a shortcut just like any other application. In Main menu, the Customer Menu is placed by default to 11th position. When the Customer Menu is enabled, Help moves from position 11 to 12 and Apps moves from 12 to 13, which is not visible until the user scrolls the menu cursor.
+
+ Customer menu icon that will be present in Application Grid. Size: 65 x 65 pixels. Format: SVGT (preferred) or BMP. Color depth: 24 bit
+
+
+
+
+
+
+ 0
+
+
+ 0
+ 0
+
+
+
+ UI/Customer Menu/Cache
+
+
+
+
+
+ true
+
+
+ false
+
+
+
+'''
+
+sequencesettings = \
+'''
+
+
+
+ This defines the Type of the element created. To create a Folder item - select "Folder". To create a bookmark item - select "Item".
+
+
+
+
+ Text field containing name for the Folder or Bookmark. Must be unique.
+
+
+
+
+
+
+ Template
+ Download Applications
+
+
+ Folder1
+ Download Applications
+
+
+ Folder2
+ Download Images
+
+
+ Folder3
+
+
+
+
+'''
+
+simpleview = \
+'''
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+ 0
+ V .50.2009.04.0113 RND
+ myProduct
+ myProduct
+
+
+
+ Image creation related settings
+
+ Sample Description
+
+
+
+
+
+'''
+
+class TestModuleGetters(unittest.TestCase):
+ def test_get_reader_for_configuration(self):
+ confread = persistentconfml.get_reader_for_elem("configuration")
+ self.assertTrue(isinstance(confread, persistentconfml.ConfigurationReader))
+
+ def test_get_writer_for_configuration(self):
+ confread = persistentconfml.get_writer_for_class("Configuration")
+ self.assertTrue(isinstance(confread, persistentconfml.ConfigurationWriter))
+
+ def test_get_elemname_from_string(self):
+ self.assertEquals(persistentconfml.get_elemname("{http://www.s60.com/xml/confml/1}configuration")[0],"http://www.s60.com/xml/confml/1")
+ self.assertEquals(persistentconfml.get_elemname("{http://www.s60.com/xml/confml/1}configuration")[1],"configuration")
+
+ def test_get_elemname_from_element_tree(self):
+ root = ElementTree.fromstring(simplerootxml)
+ for elem in root.getiterator():
+ (namespace,elemname) = persistentconfml.get_elemname(elem.tag)
+ self.assertEquals(elemname,"include")
+
+ def test_loads(self):
+ config = persistentconfml.loads(simplerootxml)
+ self.assertEquals(config.get_name(),"simple")
+
+ def test_dumps(self):
+ config = api.Configuration("test.confml")
+ config.include_configuration('path/to/config.confml')
+ dump = persistentconfml.dumps(config)
+ elem = ElementTree.fromstring(dump)
+ self.assertEquals(elem.get('name'),"test_confml")
+
+class TestConfigurationParser(unittest.TestCase):
+ def test_load_simple(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ obj = reader.loads(ElementTree.fromstring(simplerootxml))
+ self.assertEquals(obj.get_ref(),'simple')
+ self.assertEquals(obj._list(),['platform__s60__confml__test_confml'])
+
+ def test_load_new_include_confml(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ obj = reader.loads(ElementTree.fromstring(newincludexml))
+ self.assertEquals(obj._list(),['platform__s60__confml__test_confml'])
+
+ def test_load_complexrootxml(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ obj = reader.loads(ElementTree.fromstring(complexrootxml))
+ self.assertEquals(obj._list(),['platform__s60__confml__test_confml',
+ 'platform__jallaa__confml__root_confml',
+ 'configB__confml__configB_confml',
+ 'ncp33__prod__confml__root_confml'])
+
+ def test_load_morestuff(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ obj = reader.loads(ElementTree.fromstring(morestuff))
+ self.assertEquals(obj._list(),['_meta','_desc','platform__s60__confml__root_confml', 'ncp11__confml__jallaa_confml', 'ncp11__prodX__confml__root_confml', 'regional__japan__confml__root_confml'])
+ met = obj.meta
+ self.assertEquals(obj.meta[2].value,'Variant1 creator')
+ self.assertEquals(obj.meta[3].value,'somestorage:somelocation_123/and/path')
+ self.assertEquals(obj.meta[4].value,'proto_b2')
+ self.assertEquals(obj.meta[0].tag,'configuration-property')
+ self.assertEquals(obj.meta[0].value, None)
+ self.assertEquals(obj.meta[0].ns,'http://www.nokia.com/xml/cpf-id/1')
+ self.assertEquals(obj.meta[0].attrs,{"name": "coreplat_name", "value": "abc_123"})
+ self.assertEquals(obj.desc,'This is a configuration for Product1 Region1 Variant1 ')
+
+ def test_load_morestuff_and_remove_included_configuration(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ obj = reader.loads(ElementTree.fromstring(morestuff))
+ self.assertEquals(obj.list_configurations(),['platform/s60/confml/root.confml', 'ncp11/confml/jallaa.confml', 'ncp11/prodX/confml/root.confml', 'regional/japan/confml/root.confml'])
+ obj.remove_configuration('platform/s60/confml/root.confml')
+ self.assertEquals(obj.list_configurations(),['ncp11/confml/jallaa.confml', 'ncp11/prodX/confml/root.confml', 'regional/japan/confml/root.confml'])
+ for configname in obj.list_configurations():
+ obj.remove_configuration(configname)
+ self.assertEquals(obj.list_configurations(),[])
+
+ def test_load_actualconfml(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ obj = reader.loads(ElementTree.fromstring(actualconfml))
+ self.assertEquals(obj.list_features(),['KCRUidApEngineLV', 'KCRUidApSettingsHandlerUiLV','CVC_OperatorMenu'])
+ self.assertEquals(obj.list_all_features(),['KCRUidApEngineLV',
+ 'KCRUidApEngineLV.KApEngineLVFlags',
+ 'KCRUidApSettingsHandlerUiLV',
+ 'KCRUidApSettingsHandlerUiLV.KApSettingsHandlerUiLVFlags',
+ 'KCRUidApSettingsHandlerUiLV.KAIStatusPaneLayout',
+ 'CVC_OperatorMenu',
+ 'CVC_OperatorMenu.CVC_OperatorMenuIconFile',
+ 'CVC_OperatorMenu.CVC_OperatorMenuIconFile.localPath',
+ 'CVC_OperatorMenu.CVC_OperatorMenuIconFile.targetPath'])
+ fea = obj.KCRUidApSettingsHandlerUiLV.KApSettingsHandlerUiLVFlags
+ vset = fea.get_valueset()
+ self.assertTrue(fea.get_value() in vset)
+ self.assertTrue('0' in obj.KCRUidApSettingsHandlerUiLV.KAIStatusPaneLayout.get_valueset())
+ self.assertTrue('1' in obj.KCRUidApSettingsHandlerUiLV.KAIStatusPaneLayout.get_valueset())
+ for fearef in obj.list_all_features():
+ fea = obj.get_feature(fearef)
+ if fea.get_type() == 'int':
+ #print "Feature %s, %s: %s" % (fea.get_type(),fea.get_name(),fea.get_value())
+ self.assertEquals(fea.get_value(),0)
+ self.assertEquals(obj.get_feature('CVC_OperatorMenu.CVC_OperatorMenuIconFile.targetPath').get_value(),None)
+ self.assertEquals(obj.get_feature('CVC_OperatorMenu.CVC_OperatorMenuIconFile.localPath').get_value(),'UI/Customer Menu/Cache')
+
+ def test_create_features_with_rfs_data_and_dump_and_load(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('child1'),'feature1')
+ conf.add_feature(api.Feature('child2'),'feature1')
+ conf.add_feature(api.Feature('child3'),'feature1')
+
+ conf.add_data(api.Data(fqr='feature1.child1',attr='rfs',value='true'))
+ conf.add_data(api.Data(fqr='feature1.child2',attr='rfs',value='false'))
+ dview = conf.get_default_view()
+ self.assertEquals(dview.get_feature('feature1.child1').get_value(), None)
+ self.assertEquals(dview.get_feature('feature1.child1').get_value('rfs'), 'true')
+ self.assertEquals(dview.get_feature('feature1.child2').get_value('rfs'), 'false')
+
+ dumped = persistentconfml.dumps(conf)
+ conf2 = persistentconfml.loads(dumped)
+ dview = conf2.get_default_view()
+ self.assertEquals(dview.get_feature('feature1.child1').get_value(), None)
+ self.assertEquals(dview.get_feature('feature1.child1').get_value('rfs'), 'true')
+ self.assertEquals(dview.get_feature('feature1.child2').get_value('rfs'), 'false')
+
+ def test_load_actualconfml_test_rfs_settings(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ obj = reader.loads(ElementTree.fromstring(actualconfml))
+ self.assertEquals(obj.get_feature('KCRUidApEngineLV.KApEngineLVFlags').rfs,True)
+ self.assertEquals(obj.get_feature('KCRUidApSettingsHandlerUiLV.KApSettingsHandlerUiLVFlags').rfs,False)
+
+ def test_load_sequence_confml(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(sequencesettings)
+ obj = reader.loads(etree)
+ dcont = obj.get_data('BookmarkItems')
+ dview = obj.get_default_view()
+ self.assertEquals(dview.get_feature('BookmarkItems.BookmarkItem').list_features(),['Type', 'Name'])
+ self.assertEquals(dview.get_feature('BookmarkItems.BookmarkItem').list_all_features(),['Type', 'Name'])
+ datatable = dview.get_feature('BookmarkItems.BookmarkItem').get_data()
+ self.assertEquals(len(datatable), 3)
+ self.assertEquals(datatable[0].list_features(), ['Type', 'Name'])
+ self.assertEquals(datatable[0].get_feature('Name').get_value(), 'Download Applications')
+ self.assertEquals(datatable[0][0].get_value(), 'Folder1')
+ self.assertEquals(datatable[0][1].get_value(), 'Download Applications')
+ self.assertEquals(dview.get_feature('BookmarkItems.BookmarkItem').get_value(),
+ [
+ ['Folder1','Download Applications'],
+ ['Folder2','Download Images'],
+ ['Folder3',None]])
+
+ def test_load_commsdat_sequence_confml_from_file(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/commsdatcreator.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ dview = obj.get_default_view()
+ dnsfea = dview.get_feature('DNs.DN')
+ self.assertEquals(dnsfea.list_features(),['Name', 'DNId', 'Metadata', 'Protection', 'Hidden', 'HiddenAgent', 'Highlighted', 'Icon', 'EmbeddedDN', 'IAP', 'IAP2', 'IAP3', 'IAP4', 'IAP5', 'IAP6', 'IAP7', 'IAP8', 'IAP9', 'IAP10'])
+ self.assertEquals(dnsfea.get_template(),['User Defined', '0', 'No', 'No', 'No', '11', None, None, None, None, None, None, None, None, None, None, None, None, None])
+ self.assertEquals(dnsfea.get_value(),
+ [['Internet', '1', 'Internet', '2', 'No', 'No', 'Yes', '0', None, None, None, None, None, None, None, None, None, None, None],
+ ['MMS', '2', 'MMS', '2', 'No', 'Yes', 'No', '2', None, None, None, None, None, None, None, None, None, None, None],
+ ['Operator', '3', 'Operator', '2', 'No', 'No', 'No', '4', None, None, None, None, None, None, None, None, None, None, None]
+ ])
+
+ def test_load_content_sequence_confml_from_file(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/CVC_Content.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ dview = obj.get_default_view()
+ content = dview.get_feature('ContentFiles.contentfile')
+ self.assertEquals(content.list_all_features(),['fileelem', 'fileelem.localPath', 'fileelem.targetPath'])
+ self.assertEquals(content.value,[[['test/BookmarkImportSample.txt', None]]])
+ self.assertEquals(content.fileelem.localPath.value,['test/BookmarkImportSample.txt'])
+
+ def test_load_content_multiselection_confml_from_file(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('multiselection.confml')
+ dview = config.get_default_view()
+ multisel1 = dview.get_feature('MultiSelections.MultiSel1')
+ self.assertEquals(multisel1.value,["first selection","second selection"])
+ self.assertEquals(multisel1.get_data_cast(multisel1.get_value()),["first selection","second selection"])
+ self.assertEquals(multisel1.get_value(),["first selection","second selection"])
+ self.assertEquals(multisel1.get_data().get_value(),'"first selection" "second selection"')
+
+
+ def test_load_content_multiselection_empty_confml_from_file(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('multiselection.confml')
+ dview = config.get_default_view()
+ multisel1 = dview.get_feature('uda_selection.selectedfiles')
+ self.assertEquals(multisel1.get_value(),None)
+ self.assertEquals(multisel1.get_data().get_value(),None)
+
+
+
+ def test_add_sequence_data_to_separate_confml(self):
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data'),"w"))
+ config = prj.create_configuration('test2.confml')
+ seqconfig = config.create_configuration('sequence.confml')
+ config.create_configuration('testdata.confml')
+ seqconfig.add_feature(api.FeatureSequence('feature1'))
+ seqconfig.add_feature(api.Feature('child1'),'feature1')
+ seqconfig.add_feature(api.Feature('child2'),'feature1')
+ seqconfig.add_feature(api.Feature('child3'),'feature1')
+ dview = config.get_default_view()
+ self.assertEquals(dview.get_feature('feature1').get_type(),'sequence')
+ dview.get_feature('feature1').set_template(['c1','c2','c3'])
+ dview.get_feature('feature1').add_sequence(['row 1','43','56'])
+ dview.get_feature('feature1').add_sequence(['row 2','43','56'])
+ config.create_configuration('testdata2.confml')
+ dview.get_feature('feature1').add_sequence(['row 3','43','56'])
+ dview.get_feature('feature1').add_sequence(['row 4','43','56'])
+ dview.get_feature('feature1').get_data()[1].set_value(['row 2 updated', 'foo', '56'])
+ config.save()
+ prj.close()
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data')))
+ config = prj.get_configuration('test2.confml')
+ dview = config.get_default_view()
+ self.assertEquals(dview.get_feature('feature1').get_template(),['c1','c2','c3'])
+ self.assertEquals(dview.get_feature('feature1').get_value(),[['row 3', '43', '56'],
+ ['row 4', '43', '56']])
+ self.assertEquals(dview.get_feature('feature1').get_data()[0]._index,0)
+ self.assertEquals(dview.get_feature('feature1').get_data()[0].get_value(),['row 3', '43', '56'])
+ self.assertEquals(dview.get_feature('feature1').get_data()[1].get_value(),['row 4', '43', '56'])
+ self.assertEquals(dview.get_feature('feature1').get_data()[0].get_data().find_parent(type=api.Configuration), config.get_configuration('testdata2.confml')._obj)
+ prj.remove_configuration('test2.confml')
+
+
+ def test_add_sequence_data_to_separate_confml_with_append_policy(self):
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data'),"w"))
+ config = prj.create_configuration('test1.confml')
+ seqconfig = config.create_configuration('sequence.confml')
+ config.create_configuration('testdata.confml')
+ seqconfig.add_feature(api.FeatureSequence('feature1'))
+ seqconfig.add_feature(api.Feature('child1'),'feature1')
+ seqconfig.add_feature(api.Feature('child2'),'feature1')
+ seqconfig.add_feature(api.Feature('child3'),'feature1')
+ dview = config.get_default_view()
+ self.assertEquals(dview.get_feature('feature1').get_type(),'sequence')
+ dview.get_feature('feature1').set_template(['c1','c2','c3'])
+ dview.get_feature('feature1').add_sequence(['row 1','43','56'])
+ dview.get_feature('feature1').add_sequence(['row 2','43','56'])
+ config.create_configuration('testdata2.confml')
+ dview.get_feature('feature1').add_sequence(['row 3','43','56'])
+ dview.get_feature('feature1').add_sequence(['row 4','43','56'])
+ dview.get_feature('feature1').get_data()[1].set_value(['row 2 updated', 'foo', '56'])
+ config.save()
+ prj.close()
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data')))
+ config = prj.get_configuration('test1.confml')
+ dview = config.get_default_view()
+ self.assertEquals(dview.get_feature('feature1').get_template(),['c1','c2','c3'])
+ self.assertEquals(dview.get_feature('feature1').get_value(),[['row 3', '43', '56'],
+ ['row 4', '43', '56']])
+ self.assertEquals(dview.get_feature('feature1').get_data()[0]._index,0)
+ self.assertEquals(dview.get_feature('feature1').get_data()[0].get_value(),['row 3', '43', '56'])
+ self.assertEquals(dview.get_feature('feature1').get_data()[1].get_value(),['row 4', '43', '56'])
+ self.assertEquals(dview.get_feature('feature1').get_data()[0].get_data().find_parent(type=api.Configuration), config.get_configuration('testdata2.confml')._obj)
+ prj.remove_configuration('test1.confml')
+
+ def test_load_view(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(simpleview)
+ obj = reader.loads(etree)
+ self.assertEquals(obj.get_name(), 'unknown')
+ self.assertEquals(obj.list_views(), ['Image creation'])
+ self.assertEquals(obj.get_view('Image creation').get_name(),'Image creation')
+ self.assertEquals(obj.get_view('Image creation').desc,'Image creation related settings')
+ self.assertEquals(obj.get_view('Image creation').list_features(),[])
+ self.assertEquals(obj.get_view('Image creation').list_groups(),['Imageproperties'])
+ self.assertEquals(obj.get_view('Image creation').list_all_features(),['Imageproperties.imagetype',
+ 'Imageproperties.rofs3version',
+ 'Imageproperties.productname',
+ 'Imageproperties.outputLocation',
+ 'Imageproperties.imagetarget'])
+ self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.imagetype').get_value(), '0')
+ self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.rofs3version').get_value(), 'V .50.2009.04.0113 RND')
+ self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.productname').get_value(), 'myProduct')
+ self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.outputLocation').get_value(), 'myProduct')
+ self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.imagetarget').get_value(), '2')
+
+ def test_load_cvc_view(self):
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data')))
+ config = prj.get_configuration('cvc_root.confml')
+ dview = config.get_default_view()
+ self.assertEquals(config.list_views(),['cvc_view_confml.Custom modeled ConfMLs for customization foo'])
+ view = config.get_view('cvc_view_confml.Custom modeled ConfMLs for customization foo')
+ self.assertEquals(view.id, 'CVC')
+ self.assertEquals(view.list_groups(),['Applications', 'Connectivity', 'System', 'UI', 'Pre-Installed Content'])
+ self.assertEquals(view.list_features(),[])
+ group = view.get_group('Connectivity')
+ self.assertEquals(group.icon, 'connectivity_48_nav.png')
+ self.assertEquals(len(view.list_all_features()),130)
+
+
+ def test_load_booleans_confml_from_file(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/booleans.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ dview = obj.get_default_view()
+ boolfea = dview.get_feature('Booleans')
+ self.assertEquals(len(boolfea.list_features()),20)
+
+ def test_load_confml_with_properties(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/CVC_StartupShutdownAnimations.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ fea = obj.get_feature('CVC_StartupAnimationSequence.CVC_StartupAnimationTone')
+ self.assertEquals(fea.list_properties(),['maxSize'])
+ self.assertEquals(fea.properties['maxSize'].value,'100')
+
+ conffile = open(os.path.join(ROOT_PATH,"data/CVC_Preinstalled.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ fea = obj.get_feature('CVC_PreinstalledContent.CVC_PreInstalledMMSs.CVC_PreInstalledMMS')
+ self.assertEquals(fea.list_properties(),['maxFileSize'])
+ self.assertEquals(fea.properties['maxFileSize'].value,'35')
+
+ def test_load_voicemailbox_confml_from_file(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/voicemailbox.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ dview = obj.get_default_view()
+ stringfea = dview.get_feature('KCRUidVoiceMailbox.KVmbxNumberLinePrimary')
+ self.assertEquals(stringfea.type,'string')
+ self.assertEquals(stringfea.value,None)
+
+ def test_load_facets(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/facets.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ setting = obj.get_feature('Facets.MessageSize')
+ self.assertEquals(setting.minInclusive,'0')
+ self.assertEquals(setting.maxInclusive,'10')
+ setting = obj.get_feature('Facets.MessageSize2')
+ self.assertEquals(setting.minExclusive,'-1')
+ self.assertEquals(setting.maxExclusive,'11')
+ setting = obj.get_feature('Facets.StringPattern')
+ self.assertEquals(setting.pattern,"[a-zA-Z]{5,10}")
+ setting = obj.get_feature('Facets.TotalDigits')
+ self.assertEquals(setting.totalDigits,'3')
+ dview = obj.get_default_view()
+ intfea = dview.get_feature('Facets.MessageSize')
+ self.assertEquals(intfea.type,'int')
+ self.assertEquals(intfea.value,9)
+
+class TestConfigurationWriter(unittest.TestCase):
+ def test_dump_simple_configuration(self):
+ config = api.Configuration("test.confml")
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ etree = writer.dumps(config)
+ self.assertEquals(etree.get('name'), 'test_confml')
+
+ def test_dump_configuration_with_include(self):
+ config = api.Configuration("test.confml")
+ config.include_configuration('path/to/config.confml')
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ elem = writer.dumps(config)
+ etree = ElementTree.fromstring(ElementTree.tostring(elem))
+ self.assertEquals(etree.find('{http://www.w3.org/2001/XInclude}include').get('href'), 'path/to/config.confml')
+
+ def test_dump_configuration_with_feature_sequence(self):
+ config = api.Configuration("test.confml")
+ config.add_feature(api.Feature('test'))
+ config.add_feature(api.FeatureSequence('sequentialfeature'),'test')
+ config.test.sequentialfeature.add_feature(model.ConfmlSetting('setting1'))
+ config.test.sequentialfeature.add_feature(model.ConfmlSetting('setting2'))
+ config.test.sequentialfeature.add_feature(model.ConfmlSetting('setting3'))
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ elem = writer.dumps(config)
+ etree = ElementTree.fromstring(ElementTree.tostring(elem))
+ self.assertEquals([elem for elem in etree.getiterator('{http://www.s60.com/xml/confml/2}setting')][0].get('ref'), 'sequentialfeature')
+
+ def test_dump_complex_configuration(self):
+ config = api.Configuration("test.confml")
+ config.include_configuration('path/to/config1.confml')
+ config.include_configuration('path/to/config2.confml')
+ config.include_configuration('path/to/config3.confml')
+ config.add( model.ConfmlMeta([model.ConfmlMetaProperty('test', '123'),\
+ model.ConfmlMetaProperty('model', 'foo')]))
+ config.add( model.ConfmlDescription( 'Description text' ) )
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ elem = writer.dumps(config)
+ etree = ElementTree.fromstring(ElementTree.tostring(elem))
+ self.assertEquals([elem.get('href') for elem in etree.getiterator('{http://www.w3.org/2001/XInclude}include')],
+ ['path/to/config1.confml',
+ 'path/to/config2.confml',
+ 'path/to/config3.confml'
+ ])
+ meta = etree.find('{http://www.s60.com/xml/confml/2}meta')
+ self.assertEquals(meta.find('{http://www.s60.com/xml/confml/2}test').text,'123')
+ self.assertEquals(meta.find('{http://www.s60.com/xml/confml/2}model').text,'foo')
+ self.assertEquals(etree.find('{http://www.s60.com/xml/confml/2}desc').text,'Description text')
+
+ def test_dump_load_configuration(self):
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ config = model.ConfmlConfiguration("test.confml")
+ config.include_configuration('path/to/config1.confml')
+ config.include_configuration('path/to/config2.confml')
+ config.include_configuration('path/to/config3.confml')
+ config.meta = model.ConfmlMeta([model.ConfmlMetaProperty('test', '123'),\
+ model.ConfmlMetaProperty('model', 'foo'),\
+ model.ConfmlMetaProperty('configuration-property', None, \
+ 'http://www.nokia.com/xml/cpf-id/1', \
+ attrs ={"name":"123", "value": "234"})])
+ config.desc = 'Description text'
+ etree= writer.dumps(config)
+ xmlstr = ElementTree.tostring(etree)
+ config2 = persistentconfml.get_reader_for_elem("configuration").loads(ElementTree.fromstring(xmlstr))
+ self.assertEquals(config2.get_ref(),config.ref)
+ self.assertEquals(config2._list(),config._list())
+ self.assertEquals(config2.desc,'Description text')
+ elem = config2.meta.get_property_by_tag('test')
+ self.assertEquals(elem.tag, 'test')
+ self.assertEquals(elem.value, '123')
+
+ self.assertEquals(config2.meta[0].tag, 'test')
+ self.assertEquals(config2.meta[0].value, '123')
+ self.assertEquals(config2.meta[1].tag, 'model')
+ self.assertEquals(config2.meta[1].value, 'foo')
+ self.assertEquals(config2.meta[2].tag, 'configuration-property')
+ self.assertEquals(config2.meta[2].value, None)
+ self.assertEquals(config2.meta[2].ns, 'http://www.nokia.com/xml/cpf-id/1')
+ self.assertEquals(config2.meta[2].attrs, {"name":"123", "value": "234"})
+
+
+ def test_configuration_with_features_and_properties(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSetting('testfea11'))
+ config.testfea11.add_property(name='smaller',value='10')
+ config.testfea11.add_property(name='bigger',value='1', unit='B')
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea11.properties['smaller'].value,'10')
+ self.assertEquals(config2.testfea11.properties['bigger'].value,'1')
+
+ def test_configuration_with_features_and_minoccurs(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSequenceSetting('testfea11'))
+ config.testfea11.minOccurs = 1
+ config.testfea11.maxOccurs = 10
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea11.minOccurs,1)
+ self.assertEquals(config2.testfea11.maxOccurs,10)
+
+ def test_configuration_with_features_and_readonly(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSequenceSetting('testfea11'))
+ config.add_feature(model.ConfmlSetting('readme',readOnly=True))
+ config.add_feature(model.ConfmlSetting('writeme',readOnly=False))
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea11.readOnly,None)
+ self.assertEquals(config2.readme.readOnly,True)
+ self.assertEquals(config2.writeme.readOnly,False)
+
+ def test_configuration_with_features_and_constraint(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSequenceSetting('testfea11'))
+ config.add_feature(model.ConfmlSetting('const',constraint=". > '1'"))
+ config.add_feature(model.ConfmlSetting('writeme',readOnly=False, constraint='foo bar'))
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea11.constraint,None)
+ self.assertEquals(config2.const.constraint,". > '1'")
+ self.assertEquals(config2.writeme.readOnly,False)
+ self.assertEquals(config2.writeme.constraint,"foo bar")
+
+ def test_configuration_with_features_and_required_attr(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSequenceSetting('testfea11'))
+ config.add_feature(model.ConfmlSetting('requ',required=True))
+ config.add_feature(model.ConfmlSetting('writeme',required=False, readOnly=False))
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea11.required,None)
+ self.assertEquals(config2.requ.required,True)
+ self.assertEquals(config2.writeme.readOnly,False)
+ self.assertEquals(config2.writeme.required,False)
+
+ def test_configuration_with_features_and_relevant_attr(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSequenceSetting('testfea11'))
+ config.add_feature(model.ConfmlSetting('requ',relevant='testfea11'))
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea11.relevant,None)
+ self.assertEquals(config2.requ.relevant,'testfea11')
+
+ def test_configuration_with_features_and_maxlength(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSetting('testfea1', type='int'))
+ config.add_feature(model.ConfmlSetting('testfea2', type='int'))
+ config.add_feature(model.ConfmlSetting('testfea3', type='int',maxLength=100))
+ config.testfea1.maxLength = 10
+
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea1.maxLength,10)
+ self.assertEquals(config2.testfea2.maxLength,None)
+ self.assertEquals(config2.testfea3.maxLength,100)
+
+ def test_configuration_with_features_and_maxlength(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(model.ConfmlSetting('testfea1', type='int'))
+ config.add_feature(model.ConfmlSetting('testfea2', type='int'))
+ config.add_feature(model.ConfmlSetting('testfea3', type='int',minLength=100))
+ config.testfea1.minLength = 10
+
+ elem = persistentconfml.dumps(config)
+ config2 = persistentconfml.loads(elem)
+ self.assertEquals(config2.testfea1.minLength,'10')
+ self.assertEquals(config2.testfea3.minLength,'100')
+ self.assertEquals(config2.testfea2.minLength,None)
+
+ def test_configuration_with_features(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(api.Feature('testfea1'))
+ config.testfea1.add_feature(model.ConfmlSetting('testfea11'))
+ config.add_feature(api.Feature('testfea2'))
+ set1 = model.ConfmlSetting('testfea21', type='selection')
+ set1.create_option('pre', '1')
+ set1.create_option('normal', '2')
+ set1.create_option('post', '3')
+ config.add_feature(set1, 'testfea2')
+ config.add_feature(api.Feature('testfea4'))
+ config.add_feature(api.Feature('testfea5'))
+ config.add_feature(api.Feature('testfea6'))
+ set1.set_value('pre')
+ config.testfea1.set_value('foo:bar')
+ config.testfea4.set_value('4')
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ elem = writer.dumps(config)
+ #print ElementTree.tostring(elem)
+ etree = ElementTree.fromstring(ElementTree.tostring(elem))
+ fea1 = etree.find('{http://www.s60.com/xml/confml/2}feature')
+ self.assertEquals(fea1.get('ref'),'testfea1')
+ self.assertEquals(fea1.find('{http://www.s60.com/xml/confml/2}setting').get('ref'),'testfea11')
+ config2 = persistentconfml.get_reader_for_elem('configuration').loads(etree)
+ self.assertEquals(config2.testfea1.list_features(),['testfea11'])
+ self.assertEquals(config2.testfea2.list_features(),['testfea21'])
+ self.assertEquals(config2.testfea2.testfea21.get_type(),'selection')
+ self.assertTrue('1' in config2.testfea2.testfea21.get_valueset())
+ self.assertTrue('2' in config2.testfea2.testfea21.get_valueset())
+ self.assertEquals(config2.testfea2.testfea21.options['3'].get_name(), 'post')
+ self.assertEquals(config2.testfea2.testfea21.get_value(), 'pre')
+
+ def test_write_configuration_with_multiselections(self):
+ config = model.ConfmlConfiguration("test.confml")
+ config.add_feature(api.Feature('testfea1'))
+ config.testfea1.add_feature(model.ConfmlSetting('testfea11'))
+ config.add_feature(api.Feature('testfea2'))
+ set1 = model.ConfmlMultiSelectionSetting('testfea21')
+ set1.create_option('pre', '1')
+ set1.create_option('normal', '2')
+ set1.create_option('post', '3')
+ config.add_feature(set1, 'testfea2')
+ config.add_feature(api.Feature('testfea4'))
+ config.add_feature(api.Feature('testfea5'))
+ config.add_feature(api.Feature('testfea6'))
+ set1.value = ["pre","post"]
+ self.assertEquals(set1.get_data().get_value(), '"pre" "post"')
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ elem = writer.dumps(config)
+ self.assertEquals(ElementTree.tostring(elem), '"pre" "post" ')
+ etree = ElementTree.fromstring(ElementTree.tostring(elem))
+ fea1 = etree.find('{http://www.s60.com/xml/confml/2}feature')
+ self.assertEquals(fea1.get('ref'),'testfea1')
+ self.assertEquals(fea1.find('{http://www.s60.com/xml/confml/2}setting').get('ref'),'testfea11')
+ config2 = persistentconfml.get_reader_for_elem('configuration').loads(etree)
+ self.assertEquals(config2.testfea2.list_features(),['testfea21'])
+ self.assertEquals(config2.testfea2.testfea21.get_type(),'multiSelection')
+ self.assertEquals(config2.testfea2.testfea21.get_value(), ['pre', 'post'])
+
+ def test_configuration_with_view(self):
+ config = api.Configuration("view.confml")
+ config.add_view('testing')
+ view = config.get_view('testing')
+ view.add_group('group1')
+ view.add_group('group2')
+ view.add_group('group3')
+ view.group1.add(api.FeatureLink('test.foo'))
+ view.group2.add(api.FeatureLink('foo.*'))
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ elem = writer.dumps(config)
+ etree = ElementTree.fromstring(ElementTree.tostring(elem))
+ view = etree.find('{http://www.s60.com/xml/confml/2}view')
+ groups = etree.getiterator('{http://www.s60.com/xml/confml/2}group')
+ listgroups = [elem for elem in groups]
+
+ self.assertEquals(listgroups[0].get('name'), 'group1')
+ self.assertEquals(listgroups[1].get('name'), 'group2')
+ self.assertEquals(listgroups[2].get('name'), 'group3')
+ settings = [elem for elem in etree.getiterator('{http://www.s60.com/xml/confml/2}setting')]
+ self.assertEquals(settings[0].get('ref'), 'test/foo')
+ self.assertEquals(settings[1].get('ref'), 'foo/*')
+
+ def test_load_dump_reload_configuration_with_view(self):
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(simpleview)
+ obj = reader.loads(etree)
+ # Getting the view populates it and check that the writing still works
+ self.assertEquals(obj.get_view('Image creation').get_name(),'Image creation')
+ self.assertEquals(obj.get_view('Image creation').id,'imakerimage')
+ self.assertEquals(obj.get_view('Image creation').list_groups(), ['Imageproperties'])
+ writer = persistentconfml.get_writer_for_class("Configuration")
+ elem = writer.dumps(obj)
+ # Reload the configuration with view after dumping it to ensure data stays the same
+ elemstr = ElementTree.tostring(elem)
+ etree = ElementTree.fromstring(elemstr)
+ obj = reader.loads(etree)
+ self.assertEquals(obj.get_view('Image creation').get_name(),'Image creation')
+ self.failUnlessEqual(obj.get_view('Image creation').id,'imakerimage', 'Known bug (#564)')
+ self.assertEquals(obj.get_view('Image creation').id,'imakerimage')
+
+ def test_load_configuration_and_create_copy_and_dump(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/commsdatcreator.confml"))
+ #reader = persistentconfml.get_reader_for_elem("configuration")
+ #etree = ElementTree.fromstring(conffile.read())
+ obj = persistentconfml.loads(conffile.read())
+ copyconfig = api.Configuration('data/copy_commsdatcreator.confml')
+
+ for child in obj._objects():
+ copyconfig._add(child)
+ output = persistentconfml.dumps(copyconfig)
+ ofile = open(os.path.join(ROOT_PATH,'data/copy_commsdatcreator.confml'),"wb")
+ ofile.write(output)
+ ofile.close()
+ newconfig = persistentconfml.loads(output)
+ orgview = obj.get_default_view()
+ newview = newconfig.get_default_view()
+ for fea in orgview.list_all_features():
+ orgval = orgview.get_feature(fea).get_value()
+ newval = newview.get_feature(fea).get_value()
+ if not orgval == newval:
+ self.fail("Value of %s does not match. org = %s != new = %s" % (fea,orgval,newval))
+
+ def test_create_configuration_with_meta_and_dump(self):
+ prj = api.Project(api.Storage.open('dump','w'))
+ testconf = prj.create_configuration('test.confml')
+ testconf.include_configuration('test/foo.confml')
+ testconf.save()
+ prj.close()
+ prj2 = api.Project(api.Storage.open('dump','a'))
+ testconf = prj2.get_configuration('test.confml')
+ testconf.meta = model.ConfmlMeta()
+ testconf.meta.append(model.ConfmlMetaProperty('test', 'foo one two'))
+ testconf.meta.append(model.ConfmlMetaProperty('owner', 'test erik'))
+ testconf.save()
+ prj2.close()
+ prj = api.Project(api.Storage.open('dump','a'))
+ testconf = prj.get_configuration('test.confml')
+ self.assertEquals(testconf.meta[0].tag, 'test')
+ self.assertEquals(testconf.meta[0].value,'foo one two')
+ self.assertEquals(testconf.meta[1].tag, 'owner')
+ self.assertEquals(testconf.meta[1].value,'test erik')
+ del testconf.meta[1]
+ del testconf.meta
+ testconf.save()
+ prj.close()
+ prj = api.Project(api.Storage.open('dump','a'))
+ testconf = prj.get_configuration('test.confml')
+ self.assertEquals(testconf.meta, None)
+ prj.close()
+ shutil.rmtree('dump')
+
+class TestMeta(unittest.TestCase):
+ def test_get_reader_for_meta(self):
+ reader = persistentconfml.get_reader_for_elem("meta")
+ self.assertTrue(isinstance(reader, persistentconfml.MetaReader))
+
+ def test_parse_meta_elem(self):
+ reader = persistentconfml.get_reader_for_elem("meta")
+ elem = ElementTree.Element('meta')
+ owner = ElementTree.Element('owner')
+ owner.text = 'Testing owner'
+ origin = ElementTree.Element('origin')
+ origin.text = 'just origin'
+ target = ElementTree.Element('target')
+ target.text = 'target hw'
+ elem.append(owner)
+ elem.append(origin)
+ elem.append(target)
+ data = reader.loads(elem)
+ self.assertEquals(data[0].tag, 'owner')
+ self.assertEquals(data[0].value, 'Testing owner')
+ self.assertEquals(data[1].tag, 'origin')
+ self.assertEquals(data[1].value, 'just origin')
+ self.assertEquals(data[2].tag, 'target')
+ self.assertEquals(data[2].value, 'target hw')
+
+ def test_write_meta_elem(self):
+ writer = persistentconfml.get_writer_for_class("ConfmlMeta")
+ celem = model.ConfmlMeta([model.ConfmlMetaProperty('test', 123),\
+ model.ConfmlMetaProperty('owner', "some ownername"),\
+ model.ConfmlMetaProperty('target', "hw")])
+ etree = writer.dumps(celem)
+ self.assertEquals(etree.find('test').text,123)
+ self.assertEquals(etree.find('owner').text,'some ownername')
+ self.assertEquals(etree.find('target').text,'hw')
+
+#
+class TestDesc(unittest.TestCase):
+ def test_get_reader_for_desc(self):
+ reader = persistentconfml.get_reader_for_elem("desc")
+ self.assertTrue(isinstance(reader, persistentconfml.DescReader))
+
+ def test_parse_desc_elem(self):
+ reader = persistentconfml.get_reader_for_elem("meta")
+ elem = ElementTree.Element('desc')
+ elem.text = 'Testing desc'
+ data = reader.loads(elem)
+
+ def test_write_desc_elem(self):
+ writer = persistentconfml.get_writer_for_class("ConfmlDescription")
+ celem = model.ConfmlDescription('testing')
+ etree = writer.dumps(celem)
+ self.assertEquals(etree.text,'testing')
+
+class TestFeature(unittest.TestCase):
+ def test_get_reader_for_feature(self):
+ reader = persistentconfml.get_reader_for_elem("feature")
+ self.assertTrue(isinstance(reader, persistentconfml.FeatureReader))
+
+ def test_parse_feature_elem(self):
+ reader = persistentconfml.get_reader_for_elem("feature")
+ elem = ElementTree.Element('feature',
+ {'ref' : 'hiifoo',
+ 'name': 'Some other name'})
+ fea = reader.loads(elem)
+ self.assertEquals(fea.get_ref(),'hiifoo')
+ self.assertEquals(fea.get_name(),'Some other name')
+
+ def test_write_feature_elem(self):
+ writer = persistentconfml.get_writer_for_class("Feature")
+ celem = api.Feature('testing')
+ etree = writer.dumps(celem)
+ self.assertEquals(etree.get('ref'),'testing')
+ self.assertEquals(etree.get('name'),'testing')
+
+
+class TestSetting(unittest.TestCase):
+ def test_get_reader_for_feature(self):
+ reader = persistentconfml.get_reader_for_elem("setting")
+ self.assertTrue(isinstance(reader, persistentconfml.ConfmlSettingReader))
+
+ def test_parse_elem(self):
+ reader = persistentconfml.get_reader_for_elem("setting")
+ elem = ElementTree.Element('setting',
+ {'ref' : 'hiifoo',
+ 'name': 'Some other name',
+ 'type' :'int',
+ 'readOnly': 'true'})
+ fea = reader.loads(elem)
+ self.assertEquals(fea.get_ref(),'hiifoo')
+ self.assertEquals(fea.get_name(),'Some other name')
+ self.assertEquals(fea.get_type(),'int')
+
+ def test_write_setting_elem(self):
+ writer = persistentconfml.get_writer_for_class("ConfmlSetting")
+ celem = model.ConfmlSetting('testing')
+ etree = writer.dumps(celem)
+ self.assertEquals(etree.get('ref'),'testing')
+ self.assertEquals(etree.get('name'),'testing')
+ self.assertEquals(etree.get('type'),None)
+
+ def test_write_setting_with_options(self):
+ writer = persistentconfml.get_writer_for_class("ConfmlSetting")
+ elem = model.ConfmlSetting('testing', type='selection')
+ elem.create_option('one','1')
+ elem.create_option('two','2')
+ elem.create_option('three','3')
+ elem.create_option('four','bar')
+ etree = writer.dumps(elem)
+
+ self.assertEquals(etree.get('ref'),'testing')
+ self.assertEquals(etree.get('name'),'testing')
+ self.assertEquals(etree.get('type'),'selection')
+ self.assertEquals(etree.find('option').get('name'),'one')
+ self.assertEquals(etree.find('option').get('value'),'1')
+
+ def test_write_setting_with_facets(self):
+ writer = persistentconfml.get_writer_for_class("ConfmlSetting")
+ setting = model.ConfmlIntSetting(name="Int Setting", ref='intSetting')
+ setting.minInclusive = 0
+ setting.maxInclusive = 10
+ setting.minExclusive = 0
+ setting.maxExclusive = 10
+ setting.totalDigits = 3
+ setting.pattern = "\d*{3}"
+ etree = writer.dumps(setting)
+
+ self.assertEquals(etree.find('xs:minInclusive').get('value'),'0')
+ self.assertEquals(etree.find('xs:maxInclusive').get('value'),'10')
+ self.assertEquals(etree.find('xs:minExclusive').get('value'),'0')
+ self.assertEquals(etree.find('xs:maxExclusive').get('value'),'10')
+ self.assertEquals(etree.find('xs:totalDigits').get('value'),'3')
+ self.assertEquals(etree.find('xs:pattern').get('value'),'\d*{3}')
+
+ conffile = open(os.path.join(ROOT_PATH,"data/facets.confml"))
+ obj = persistentconfml.loads(conffile.read())
+
+ new_path = os.path.join(ROOT_PATH,"temp/facets_dumped.confml")
+ dir = os.path.dirname(new_path)
+ if dir and not os.path.exists(dir):
+ os.makedirs(dir)
+ f = open(new_path,"wb")
+ try: f.write(persistentconfml.dumps(obj))
+ finally: f.close()
+
+ def test_read_setting_with_options(self):
+ reader = persistentconfml.get_reader_for_elem("setting")
+ elem = ElementTree.Element('setting', {'ref' : 'hii',
+ 'name': 'hoo hii',
+ 'type': 'selection'})
+ elem.append(ElementTree.Element('option', {'name': 'test1', 'value': '123'}))
+ elem.append(ElementTree.Element('option', {'name': 'test2', 'value': '456'}))
+ elem.append(ElementTree.Element('option', {'name': 'test3', 'value': '789'}))
+ setobj = reader.loads(elem)
+ vset = setobj.get_valueset()
+ self.assertTrue('123' in vset)
+ self.assertTrue('456' in vset)
+ self.assertTrue('789' in vset)
+ self.assertEquals(setobj.options['123'].get_value(),'123')
+ self.assertEquals(setobj.options['456'].get_value(),'456')
+ self.assertEquals(setobj.options['789'].get_value(),'789')
+
+ def test_read_sequence_setting(self):
+ reader = persistentconfml.get_reader_for_elem("setting")
+ elem = ElementTree.Element('setting', {'ref' : 'hii',
+ 'name': 'hoo hii',
+ 'type': 'sequence'})
+ elem.append(ElementTree.Element('setting', {'ref' : 'intsetting',
+ 'name': 'intme',
+ 'type': 'int'}))
+ elem.append(ElementTree.Element('setting', {'ref' : 'strsetting',
+ 'name': 'strme',
+ 'type': 'string'}))
+ setobj = reader.loads(elem)
+ self.assertEquals(setobj.list_features(), ['intsetting', 'strsetting'])
+ self.assertEquals(setobj.intsetting.fqr, 'hii.intsetting')
+
+ def test_read_sequence_setting_with_mapping(self):
+ reader = persistentconfml.get_reader_for_elem("setting")
+ elem = ElementTree.Element('setting', {'ref' : 'hii',
+ 'name': 'hoo hii',
+ 'type': 'sequence',
+ 'mapKey': 'intsetting',
+ 'mapValue': 'strsetting'})
+ elem.append(ElementTree.Element('setting', {'ref' : 'intsetting',
+ 'name': 'intme',
+ 'type': 'int'}))
+ elem.append(ElementTree.Element('setting', {'ref' : 'strsetting',
+ 'name': 'strme',
+ 'type': 'string'}))
+ setobj = reader.loads(elem)
+ self.assertEqual(setobj.get_map_key().name,"intme")
+ self.assertEqual(setobj.get_map_value().name,"strme")
+
+class TestSettingData(unittest.TestCase):
+ def test_get_reader_for_data(self):
+ reader = persistentconfml.get_reader_for_elem("data")
+ self.assertTrue(isinstance(reader, persistentconfml.DataReader))
+
+ def test_get_writer_for_data(self):
+ writer = persistentconfml.get_writer_for_class("Data")
+ self.assertTrue(isinstance(writer, persistentconfml.DataWriter))
+
+ def test_dump_data(self):
+ writer = persistentconfml.get_writer_for_class("Data")
+ dobj = api.Data(ref='foo', value=1)
+ elem = writer.dumps(dobj)
+ self.assertEquals(elem.text, 1)
+
+ def test_dump_data_with_subref(self):
+ writer = persistentconfml.get_writer_for_class("DataContainer")
+ base = api.DataContainer('foo')
+ base._add(api.Data(fqr='foo.bar', value='test'))
+ elem = writer.dumps(base)
+ self.assertEquals(elem.find('bar').text, 'test')
+
+ def test_dump_data_with_long_ref(self):
+ writer = persistentconfml.get_writer_for_class("Data")
+ base = api.Data(ref='foo')
+ base._add(api.Data(ref='bar'))
+ base._add_to_path('bar',api.Data(ref='test', value='test'))
+ elem = writer.dumps(base)
+ self.assertEquals(elem.find('bar').find('test').text, 'test')
+
+ def test_dump_data_with_hierarchy(self):
+ writer = persistentconfml.get_writer_for_class("Data")
+ base = api.DataContainer('foo')
+ base._add(api.Data(fqr='foo.bar', value='test'))
+ elem = writer.dumps(base)
+ self.assertEquals(elem.find('bar').text, 'test')
+
+ def test_read_data_with_map(self):
+ reader = persistentconfml.get_reader_for_elem("data")
+ data = ElementTree.Element('data')
+ feature = ElementTree.Element('foo')
+ data.append(feature)
+ feature.append(ElementTree.Element('bar', {'map' : "foo/bar[@key='key 1']"}))
+
+ obj = reader.loads(data)
+ bar = obj._get('foo.bar')
+ self.assertEqual(bar.get_map(),"foo/bar[@key='key 1']")
+
+ def test_load_confml_with_meta(self):
+ conffile = open(os.path.join(ROOT_PATH,"data/accessoryserver.confml"))
+ reader = persistentconfml.get_reader_for_elem("configuration")
+ etree = ElementTree.fromstring(conffile.read())
+ obj = reader.loads(etree)
+ self.assertEquals(obj.meta.get('type'), 'featurelist')
+
+class TestReadWriteConfml(BaseTestCase):
+ """
+ Test case for ensuring that reading in a ConfML file and then writing
+ it out again results in logically the same data (XML-wise) as the
+ original data was.
+ """
+
+ def _normalize_xml_data(self, data):
+ """
+ Normalize XML data so that it can be compared using a binary
+ comparison.
+ """
+ etree = ElementTree.fromstring(data)
+ persistence.indent(etree)
+ normalized_data = ElementTree.tostring(etree)
+ return normalized_data
+
+ def _run_read_and_write_test(self, file_name, input_dir, output_dir):
+ file_path = os.path.join(input_dir, file_name)
+
+ f = open(file_path, "rb")
+ try: original_data = f.read()
+ finally: f.close()
+
+ original_data_normalized = self._normalize_xml_data(original_data)
+
+ model = persistentconfml.loads(original_data)
+ model_data = persistentconfml.dumps(model)
+
+ model_data_normalized = self._normalize_xml_data(model_data)
+
+ PATH_ORIGINAL = os.path.join(output_dir, 'original', file_name)
+ PATH_DUMPED = os.path.join(output_dir, 'dumped', file_name)
+
+ if original_data_normalized != model_data_normalized:
+ def write(file_path, data):
+ file_dir = os.path.dirname(file_path)
+ if not os.path.exists(file_dir):
+ os.makedirs(file_dir)
+ f = open(file_path, "wb")
+ try: f.write(data)
+ finally: f.close()
+
+ write(PATH_ORIGINAL, original_data_normalized)
+ write(PATH_DUMPED, model_data_normalized)
+ self.fail("Known bug (#506)")
+ self.fail("Read-write output for file '%s' is different, see the files in '%s'" % (file_name, output_dir))
+ else:
+ # Test was successful, remove any old files that might have been there,
+ # so that the output directories only contain files for the tests that
+ # failed
+ self.remove_if_exists(PATH_ORIGINAL)
+ self.remove_if_exists(PATH_DUMPED)
+
+ def _run_test_for_file(self, file_path):
+ self._run_read_and_write_test(
+ file_name = os.path.basename(file_path),
+ input_dir = os.path.dirname(file_path),
+ output_dir = os.path.normpath(os.path.join(ROOT_PATH, 'temp/read_write_results')))
+
+# Create a separate test method for each ConfML file in the read-write test data
+_READ_WRITE_TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata/read_write')
+for filename in filter(lambda fn: fn.endswith('.confml'), os.listdir(_READ_WRITE_TESTDATA_DIR)):
+ path = os.path.join(_READ_WRITE_TESTDATA_DIR, filename)
+ test_method_name = 'test_read_write_file__%s' % filename.replace('.', '_')
+
+ # Use a separate function to create and set the lambda function on the
+ # test class, because otherwise 'path' would be the last one value set to
+ # it in the for loop
+ def _register_test_method(path):
+ method = lambda self: self._run_test_for_file(path)
+ method.__name__ = test_method_name
+ setattr(TestReadWriteConfml, test_method_name, method)
+ _register_test_method(path)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys,os
+
+__all__ = []
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+TESTAUTO_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../testautomation'))
+if SOURCE_ROOT not in sys.path:
+ sys.path.append(SOURCE_ROOT)
+if TESTAUTO_ROOT not in sys.path:
+ sys.path.insert(0,TESTAUTO_ROOT)
+
+# Find all unittest_*.py files in this folder
+import re
+__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
+# Strip .py endings
+__all__ = map(lambda name: name[:-3], __all__)
+
+def collect_suite():
+ sys.path.insert(0, ROOT_PATH)
+ try:
+ suite = unittest.TestSuite()
+ for test_module in __all__:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+ finally:
+ del sys.path[0]
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/testdata/multiroot_test.zip
Binary file configurationengine/source/cone/core/tests/testdata/multiroot_test.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/testdata/test_project.cpf
Binary file configurationengine/source/cone/core/tests/testdata/test_project.cpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/unittest_configuration.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/unittest_configuration.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,149 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+
+import __init__
+from cone.public import api, plugin
+from cone.core import *
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+test_project = os.path.join(ROOT_PATH,"testdata/test_project.cpf")
+multiroot_project = os.path.join(ROOT_PATH,"testdata/multiroot_test.zip")
+
+class TestConfiguration(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ # @test
+ def test_create_configuration(self):
+ conf = api.Configuration("foobar/testmee.confml")
+ self.assertTrue(conf)
+
+ def test_get_root(self):
+ conf = api.Configuration("foobar/testmee.confml")
+ self.assertEquals(conf.get_path(),"foobar/testmee.confml")
+
+ def test_add_layer(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.add_configuration(api.Configuration("foo.confml",namespace="foo"))
+ self.assertEquals(conf.list_configurations(),["foo.confml"])
+
+ def test_meta_desc(self):
+ conf = api.Configuration("test.confml")
+ conf.meta = {'test':'data','test2':'value'}
+ conf.desc = "Description osos"
+ self.assertEquals(conf.meta['test'],"data")
+ self.assertEquals(conf.meta['test2'],"value")
+ self.assertEquals(conf.desc,"Description osos")
+
+
+ def test_project_list_all_sequence_features(self):
+ fs = api.Storage.open(test_project)
+ p = api.Project(fs)
+ config = p.get_configuration('root5.confml')
+ view = config.get_default_view()
+ print "Fealist %s." % len(view.list_all_features())
+ self.assertEquals(len(view.list_all_features()), 62)
+ for feaname in view.list_all_features():
+ fea = view.get_feature(feaname)
+ if fea.get_type() == 'sequence':
+ print "%s" % feaname,
+ print " = %s" % fea.get_value()
+
+ def test_get_implml_container(self):
+ fs = api.Storage.open(test_project)
+ p = api.Project(fs)
+ config = p.get_configuration('root5.confml')
+ implcont = plugin.get_impl_set(config, 'foo$')
+ self.assertEquals(implcont.list_implementation(),[])
+
+ def test_multiple_open_configurations_in_one_project(self):
+ prj = api.Project(api.Storage.open(multiroot_project, "r"))
+
+ conf1 = prj.get_configuration('root1.confml')
+
+ # Getting the same configuration again should return the same object
+ self.assertTrue(conf1 is prj.get_configuration('root1.confml'))
+
+ conf2 = prj.get_configuration('root2.confml')
+ self.assertFalse(conf1 is conf2)
+
+ # Test getting default views
+ dview1 = conf1.get_default_view()
+ dview2 = conf2.get_default_view()
+ dview3 = prj.get_configuration('root3.confml').get_default_view()
+ dview4 = prj.get_configuration('root4.confml').get_default_view()
+ dview5 = prj.get_configuration('root5.confml').get_default_view()
+ self.assertFalse(dview1 is dview2)
+ self.assertFalse(dview2 is dview3)
+ self.assertFalse(dview3 is dview4)
+ self.assertFalse(dview4 is dview5)
+ self.assertTrue(dview1 is conf1.get_default_view())
+
+ # Test listing features from different configurations
+ self.assertEquals(dview1.list_all_features(), dview2.list_all_features())
+ self.assertEquals(dview2.list_all_features(), dview3.list_all_features())
+ # Layer 4 introduces a new feature
+ self.assertNotEquals(dview3.list_all_features(), dview4.list_all_features())
+ self.assertTrue('Layer4Feature' in dview4.list_all_features())
+ self.assertTrue('Layer4Feature.RealSetting' in dview4.list_all_features())
+ self.assertEquals(dview4.list_all_features(), dview5.list_all_features())
+
+ # Test getting the same feature from different configurations
+ FEATURE_REF = 'Feature1.StringSetting'
+ ss1 = dview1.get_feature(FEATURE_REF)
+ ss2 = dview2.get_feature(FEATURE_REF)
+ ss3 = dview3.get_feature(FEATURE_REF)
+ ss4 = dview4.get_feature(FEATURE_REF)
+ ss5 = dview5.get_feature(FEATURE_REF)
+ self.assertFalse(ss1 is ss2)
+ self.assertFalse(ss2 is ss3)
+ self.assertFalse(ss3 is ss4)
+ self.assertFalse(ss4 is ss5)
+
+ # Test getting values for the features
+ self.assertEquals(ss1.get_value(), 'default string')
+ self.assertEquals(ss2.get_value(), 'layer 2 string')
+ self.assertEquals(ss3.get_value(), 'layer 3 string')
+ self.assertEquals(ss4.get_value(), 'layer 4 string')
+ # Layer 5 contains no data, so the value should be the same as on layer 4
+ self.assertEquals(ss5.get_value(), 'layer 4 string')
+
+
+#if __name__ == '__main__':
+# unittest.main()
+
+
+def profile_project_list_all_features():
+ fs = api.Storage.open(configproject)
+ p = api.Project(fs)
+ config = p.get_configuration('s60.confml')
+ view = config.get_default_view()
+ print "Fealist %s." % len(view.list_all_features())
+ #for fea in view.list_all_features():
+ # if view.get_feature(fea).get_type() == 'sequence':
+ # print "%s" % fea
+ # print " = %s" % view.get_feature(fea).get_value()
+if __name__ == '__main__':
+
+ import cProfile
+ cProfile.run('profile_project_list_all_features()',None,'time')
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/unittest_configuration_project_export.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_export.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,214 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the CPF configuration
+"""
+import unittest
+import string
+import sys,os,shutil
+import difflib, zipfile
+
+import __init__
+
+from cone.public import exceptions,utils, api
+from cone.storage.filestorage import FileStorage
+from cone.storage.zipstorage import ZipStorage
+from testautomation import unzip_file
+from testautomation.base_testcase import BaseTestCase
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+temp_dir = os.path.join(ROOT_PATH,"temp/export")
+test_cpf = os.path.join(ROOT_PATH,"testdata/test_project.cpf")
+datafolder = os.path.join(ROOT_PATH,"../../storage/tests/data")
+tempzip = os.path.join(temp_dir, "exported.zip")
+
+class TestConeProjectExport(BaseTestCase):
+ def setUp(self):
+ if not os.path.exists(temp_dir):
+ os.makedirs(temp_dir)
+
+ def test_export_to_zipstorage(self):
+ test_project_dir = os.path.join(temp_dir, "test_project_1")
+ unzip_file.unzip_file(test_cpf, test_project_dir, delete_if_exists=True)
+
+ export_zip = os.path.join(temp_dir, "configexport.zip")
+
+ fs = FileStorage(test_project_dir)
+ p = api.Project(fs)
+ conf = p.get_configuration('root5.confml')
+ zs = ZipStorage(export_zip,"w")
+ zp = api.Project(zs)
+ conf_files = conf.list_resources()
+ files1 = ['.metadata']
+ files1.extend(conf_files)
+ p.export_configuration(conf,zs)
+ zp.close()
+ self.assertTrue(os.path.exists(export_zip))
+ zfile = zipfile.ZipFile(export_zip,"r")
+ files2 = zfile.namelist()
+ zfile.close()
+ files1.sort()
+ files2.sort()
+ for i in range(len(files1)):
+ self.assertEquals(files1[i],files2[i])
+ os.unlink(export_zip)
+
+ def test_export_from_files_to_zipstorage_add(self):
+ test_project_dir = os.path.join(temp_dir, "test_project_1")
+ unzip_file.unzip_file(test_cpf, test_project_dir, delete_if_exists=True)
+
+ export_zip = os.path.join(temp_dir, "configexport2.zip")
+
+ fs = FileStorage(test_project_dir)
+ p = api.Project(fs)
+ exportconf = p.get_configuration('root4.confml')
+ compareconf = p.get_configuration('root5.confml')
+ zs = ZipStorage(export_zip,"w")
+ zp = api.Project(zs)
+ conf_files = compareconf.list_resources()
+ files1 = ['.metadata']
+ files1.extend(conf_files)
+ p.export_configuration(exportconf,zs)
+ zp.close()
+ self.assertTrue(os.path.exists(export_zip))
+
+ #Re-opening in append mode for adding new layers.
+ zs = ZipStorage(export_zip,"a")
+ zp = api.Project(zs)
+ conf = p.get_configuration('Layer5/root.confml')
+ p.export_configuration(conf,zs)
+ zp.save()
+ zp.close()
+
+ zfile = zipfile.ZipFile(export_zip,"r")
+ files2 = zfile.namelist()
+ #Root file renaming.
+ files2[files2.index('root4.confml')] = 'root5.confml'
+ zfile.close()
+ files1.sort()
+ files2.sort()
+
+ for i in range(len(files1)):
+ self.assertEquals(files1[i],files2[i])
+ os.unlink(export_zip)
+
+
+ def test_export_from_zip_to_zipstorage_add(self):
+ export_zip = os.path.join(temp_dir, "configexport2.zip")
+ zs_source = ZipStorage(test_cpf,'r')
+ p = api.Project(zs_source)
+ exportconf = p.get_configuration('root4.confml')
+ compareconf = p.get_configuration('root5.confml')
+
+ zs_target = ZipStorage(export_zip,"w")
+ zp = api.Project(zs_target)
+ conf_files = compareconf.list_resources()
+ files1 = ['.metadata']
+ files1.extend(conf_files)
+ p.export_configuration(exportconf,zs_target)
+ zp.close()
+ self.assertTrue(os.path.exists(export_zip))
+
+ #Re-opening in append mode for adding new layers.
+ zs_target = ZipStorage(export_zip,"a")
+ zp = api.Project(zs_target)
+ conf = p.get_configuration('Layer5/root.confml')
+ p.export_configuration(conf,zs_target)
+ zp.save()
+ zp.close()
+
+ zfile = zipfile.ZipFile(export_zip,"r")
+ files2 = zfile.namelist()
+ #Root file renaming.
+ files2[files2.index('root4.confml')] = 'root5.confml'
+ zfile.close()
+ files1.sort()
+ files2.sort()
+
+ for i in range(len(files1)):
+ self.assertEquals(files1[i],files2[i])
+ os.unlink(export_zip)
+
+
+ def test_export_from_zipstorage(self):
+ output_dir = os.path.join(temp_dir, "export_from_zipstorage")
+ self.remove_if_exists(output_dir)
+
+ zs = ZipStorage(test_cpf,"r")
+ p = api.Project(zs)
+ fs = FileStorage(output_dir,"w")
+ r = api.Project(fs)
+ conf = p.get_configuration('root5.confml')
+ conf_files = conf.list_resources()
+ conf_files.append('.metadata')
+ p.export_configuration(conf,fs)
+ p.close()
+ r.close()
+ self.assertTrue(os.path.exists(output_dir))
+
+ # Temporarly hacked to pass, because feature is not supported
+# def test_export_to_zipstorage_multiple_configurations(self):
+# try:
+# fs = FileStorage(datafolder)
+# p = api.Project(fs)
+# zs = ZipStorage(tempzip,"w")
+# zp = api.Project(zs)
+# conf = p.get_configuration('morestuff.confml')
+# conf_files = conf.list_resources()
+# p.export_configuration(conf,zs)
+# conf = p.get_configuration('prodX.confml')
+# conf_files2 = conf.list_resources()
+# conf_files.extend(conf_files2)
+# conf_files = utils.distinct_array(conf_files)
+# p.export_configuration(conf,zs)
+# zp.close()
+# self.assertTrue(os.path.exists(tempzip))
+# zfile = zipfile.ZipFile(tempzip,"r")
+# files = zfile.namelist()
+# files.remove('.metadata')
+# self.assertEquals(sorted(conf_files),sorted(files))
+# except exceptions.NotSupportedException:
+# pass
+
+ def test_export_to_filestorage_multiple_configurations(self):
+ fs = FileStorage(datafolder)
+ p = api.Project(fs)
+ fs2 = FileStorage("temp/exported","w")
+ p2 = api.Project(fs2)
+ conf = p.get_configuration('morestuff.confml')
+ conf_files = conf.list_resources()
+ p.export_configuration(conf,fs2)
+ conf = p.get_configuration('prodX.confml')
+ conf_files.extend(conf.list_resources())
+
+ p.export_configuration(conf,fs2)
+ p2.close()
+ self.assertTrue(os.path.exists("temp/exported"))
+
+ files = fs2.list_resources("/",True)
+ conf_files = utils.distinct_array(conf_files)
+ files.sort()
+ conf_files.append('.metadata')
+ conf_files.sort()
+ self.assertEquals(conf_files,files)
+ shutil.rmtree("temp")
+
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/unittest_configuration_project_import.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_import.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,147 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the CPF configuration
+"""
+import unittest
+import string
+import sys,os,shutil
+import difflib, zipfile
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+from testautomation import unzip_file
+
+from cone.public import exceptions, utils, api
+from cone.storage.filestorage import FileStorage
+from cone.storage.zipstorage import ZipStorage
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+temp_dir = os.path.join(ROOT_PATH, "temp/import")
+test_cpf = os.path.join(ROOT_PATH,"testdata/test_project.cpf")
+datafolder = os.path.join(ROOT_PATH,"../../storage/tests/data")
+
+
+class TestConeProjectImport(unittest.TestCase):
+ def setUp(self):
+ if not os.path.exists(temp_dir):
+ os.makedirs(temp_dir)
+
+ def test_import_to_zipstorage(self):
+ test_project_dir = os.path.join(temp_dir, "test_project_1")
+ unzip_file.unzip_file(test_cpf, test_project_dir, delete_if_exists=True)
+
+ imported_zip = os.path.join(temp_dir, "imported1.zip")
+
+ fs = FileStorage(test_project_dir)
+ p = api.Project(fs)
+ zs = ZipStorage(imported_zip,"w")
+ zp = api.Project(zs)
+ conf = p.get_configuration('root5.confml')
+ conf_files = conf.list_resources()
+ conf_files.append('.metadata')
+ zp.import_configuration(conf)
+ zp.close()
+ p.close()
+ self.assertTrue(os.path.exists(imported_zip))
+ zfile = zipfile.ZipFile(imported_zip,"r")
+ files = zfile.namelist()
+ conf_files.sort()
+ files.sort()
+ self.assertEquals(conf_files,files)
+ zfile.close()
+ os.unlink(imported_zip)
+
+ def test_import_to_zipstorage_multiple_configurations(self):
+ imported_zip = os.path.join(temp_dir, "imported2.zip")
+ fs = FileStorage(datafolder)
+ p = api.Project(fs)
+ zs = ZipStorage(imported_zip,"w")
+ zp = api.Project(zs)
+ conf = p.get_configuration('morestuff.confml')
+ conf_files = conf.list_resources()
+ zp.import_configuration(conf)
+ conf = p.get_configuration('prodX.confml')
+ conf_files.extend(conf.list_resources())
+ zp.import_configuration(conf)
+ zp.close()
+ p.close()
+ self.assertTrue(os.path.exists(imported_zip))
+ zfile = zipfile.ZipFile(imported_zip,"r")
+ files = zfile.namelist()
+ files.remove('.metadata')
+ conf_files = utils.distinct_array(conf_files)
+ conf_files.sort()
+ files.sort()
+ for i in range(len(conf_files)):
+ self.assertEquals(conf_files[i], files[i])
+ zfile.close()
+ os.unlink(imported_zip)
+
+ def test_import_to_filestorage_multiple_configurations(self):
+ fs = FileStorage(datafolder)
+ p = api.Project(fs)
+ fs2 = FileStorage("temp/imported","w")
+ p2 = api.Project(fs2)
+ conf = p.get_configuration('morestuff.confml')
+ conf_files = conf.list_resources()
+ p2.import_configuration(conf)
+ conf = p.get_configuration('prodX.confml')
+ conf_files.extend(conf.list_resources())
+
+ p2.import_configuration(conf)
+ p2.close()
+ self.assertTrue(os.path.exists("temp/imported"))
+ files = fs2.list_resources("/",True)
+
+ conf_files = utils.distinct_array(conf_files)
+ conf_files.append('.metadata')
+ files.sort()
+ conf_files.sort()
+ self.assertEquals(conf_files,files)
+ shutil.rmtree("temp")
+
+ def test_import_from_zipstorage_to_filestorage(self):
+ imported_folder = os.path.join(temp_dir, 'imported1_folder')
+ p = api.Project(api.Storage.open(test_cpf))
+ rp = api.Project(api.Storage.open(imported_folder,"w"))
+ conf = p.get_configuration(p.get_storage().get_active_configuration())
+ conf_files = conf.list_resources()
+ conf_files.append('.metadata')
+ rp.import_configuration(conf)
+ rp.close()
+ p.close()
+ self.assertTrue(os.path.exists(imported_folder))
+ store = api.Storage.open(imported_folder)
+ files = store.list_resources('',True)
+ conf_files.sort()
+ files.sort()
+ self.assertEquals(conf_files,files)
+ shutil.rmtree(imported_folder)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/unittest_configuration_project_on_filestorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_on_filestorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,284 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the CPF configuration
+"""
+import unittest
+import string
+import sys,os
+import shutil
+import __init__
+from testautomation.base_testcase import BaseTestCase
+
+from cone.public import exceptions, api
+from cone.confml.model import ConfmlMeta, ConfmlDescription
+from cone.storage.filestorage import FileStorage
+from cone.confml import model
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+temp_dir = os.path.join(ROOT_PATH, "temp/project_on_filestorage")
+datafolder= os.path.join(ROOT_PATH,"../../storage/tests/data")
+
+class TestConeProjectOpen(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_open_storage(self):
+ p = api.Storage.open(datafolder)
+ self.assertTrue(p)
+
+ def test_open_project_of_non_storage(self):
+ fs = "foobar_dummy"
+ try:
+ p = api.Storage.open(fs)
+ self.fail("Opening on top of non storage succeeds!!")
+ except exceptions.StorageException:
+ self.assertTrue(True)
+
+
+class TestConeProjectMethodsRead(unittest.TestCase):
+ def setUp(self):
+ self.project = api.Project(api.Storage.open(datafolder))
+
+ def test_list_configurations(self):
+ confs = self.project.list_configurations()
+ self.assertTrue(confs)
+ self.assertEquals(confs[0],"morestuff.confml")
+
+ def test_get_configuration(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ self.assertTrue(conf)
+ self.assertTrue(isinstance(conf,api.ConfigurationProxy))
+
+ def test_get_configuration_non_existing(self):
+ try:
+ conf = self.project.get_configuration("foo.confml")
+ self.fail("Opening non existing configuration succeeds!")
+ except exceptions.NotFound,e:
+ self.assertTrue(True)
+
+ def test_get_configuration_and_list_layers(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ layers = conf.list_configurations()
+ self.assertTrue(layers)
+ self.assertEquals(layers[0],'platform/s60/root.confml')
+ self.assertEquals(layers[1],'familyX/root.confml')
+
+ def test_get_is_configuration(self):
+ self.assertTrue(self.project.is_configuration("morestuff.confml"))
+ # TODO: this is not working at the moment due to performance problem in
+ # Project.list_all_configurations()
+ #self.assertTrue(self.project.is_configuration("platform/s60/root.confml"))
+ #self.assertFalse(self.project.is_configuration("platform/foo/root.confml"))
+
+ def test_get_configuration_and_get_layer(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ s60layer = conf.get_configuration('platform/s60/root.confml')
+ self.assertTrue(s60layer)
+ self.assertTrue(isinstance(s60layer.get_layer(),api.Layer))
+
+ def test_get_configuration_and_get_layer_path(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ s60layer = conf.get_configuration('platform/s60/root.confml')
+ self.assertEquals(s60layer.get_path(),'platform/s60/root.confml')
+
+ def test_get_configuration_and_get_layer_and_get_layer_resources(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ s60layer = conf.get_configuration('platform/s60/root.confml')
+ files = s60layer.list_resources()
+ self.assertEquals(files[0],'platform/s60/root.confml')
+
+ def test_get_configuration_and_get_layer_and_get_a_layer_resource(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ s60layer = conf.get_configuration('platform/s60/root.confml')
+ res = s60layer.get_resource('root.confml')
+ self.assertTrue(res)
+
+ def test_get_configuration_and_list_all_configuration_resources(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ resources = conf.list_resources()
+ self.assertEquals(resources[0],'morestuff.confml')
+
+ def test_get_configuration_and_get_first_layer_by_index(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ s60config = conf.get_configuration_by_index(0)
+ self.assertEquals(s60config.get_path(),'platform/s60/root.confml')
+
+ def test_get_configuration_and_get_last_layer_by_index(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ config = conf.get_configuration_by_index(-1)
+ self.assertEquals(config.get_path(),'familyX/prodX/root.confml')
+
+ def test_get_all_resources(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ resources = conf.get_all_resources()
+ self.assertEquals(resources[0].get_path(),'morestuff.confml')
+ self.assertEquals(resources[1].get_path(),'platform/s60/root.confml')
+
+ def test_list_confmls(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ confmls = conf.list_resources()
+ self.assertEquals(confmls[0],'morestuff.confml')
+ self.assertEquals(confmls[1],'platform/s60/root.confml')
+
+ def test_list_implmls(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ implmls = conf.get_configuration('platform/s60/root.confml').get_layer().list_implml()
+ self.assertEquals(implmls[0],'implml/accessoryserver_1020505A.crml')
+
+# def test_list_content(self):
+# conf = self.project.get_configuration("morestuff.confml")
+# contents = conf.list_content()
+# self.assertEquals(contents[0],'platform/s60/content/.svn/all-wcprops')
+
+ def test_layered_content(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ contents = conf.layered_content()
+ self.assertEquals(contents.get_value('test/s60.txt'),'platform/s60/content/test/s60.txt')
+ self.assertEquals(contents.get_value('test/override.txt'),'familyX/content/test/override.txt')
+ self.assertEquals(contents.get_value('test/shout.txt'),'familyX/content/test/shout.txt')
+
+ def test_layer_name(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ s60layer = conf.get_configuration('platform/s60/root.confml')
+ self.assertEquals(s60layer.get_ref(),'platform__s60__root_confml')
+
+
+ def test_layered_content_with_one_layer(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ contents = conf.layered_content([-2])
+ self.assertEquals(contents.get_value('test/override.txt'),'familyX/content/test/override.txt')
+ self.assertEquals(contents.get_value('test/shout.txt'),'familyX/content/test/shout.txt')
+ try:
+ contents.get_value('test/s60.txt')
+ self.fail("Fetching content from s60 layer succeeds!")
+ except KeyError:
+ pass
+
+ def test_layered_content_with_two_layers(self):
+ conf = self.project.get_configuration("morestuff.confml")
+ contents = conf.layered_content([-2,-1])
+ self.assertEquals(contents.get_value('test/override.txt'),'familyX/content/test/override.txt')
+ self.assertEquals(contents.get_value('test/shout.txt'),'familyX/content/test/shout.txt')
+ self.assertEquals(contents.get_value('prodX/jee/ProdX_specific.txt'),'familyX/prodX/content/prodX/jee/ProdX_specific.txt')
+ try:
+ contents.get_value('test/s60.txt')
+ self.fail("Fetching content from s60 layer succeeds!")
+ except KeyError:
+ pass
+
+
+
+
+class TestConeProjectMethodsWrite(BaseTestCase):
+ def setUp(self):
+ if not os.path.exists(temp_dir):
+ os.makedirs(temp_dir)
+
+ if not os.path.exists('newtempproject'):
+ os.mkdir('newtempproject')
+ fs = api.Storage.open("newtempproject","a")
+ self.project = api.Project(fs)
+
+ def tearDown(self):
+ self.project.close()
+ shutil.rmtree('newtempproject')
+ pass
+
+ def test_create_configuration(self):
+ conf = self.project.create_configuration("dummy.confml")
+ self.assertTrue(conf)
+ self.assertEquals(conf.get_ref(),'dummy_confml')
+ self.assertTrue(isinstance(conf,api.Configuration))
+ conf.close()
+
+ def test_create_close_open_configuration(self):
+ tempdir_orig = os.path.normpath(os.path.join(temp_dir, "temp1_orig"))
+ tempdir_copy = os.path.normpath(os.path.join(temp_dir, "temp1_copy"))
+ self.remove_if_exists([tempdir_orig, tempdir_copy])
+
+ project = api.Project(api.Storage.open(tempdir_orig,"w"))
+ conf = project.create_configuration("dummy2.confml")
+ conf.set_name("dummy")
+ prop1 = model.ConfmlMetaProperty('owner', 'some guy')
+ prop2 = model.ConfmlMetaProperty('purpose', 'for testing')
+ conf.meta = model.ConfmlMeta([prop1, prop2])
+ conf.desc = "Testing to see a configuration created"
+ conf.create_configuration("test/path/to/somewhere/r.confml")
+ conf.create_configuration("test/path/to/elsewhere/r.confml")
+ conf.save()
+ project.save()
+ project.close()
+
+ # Make a copy of the created directory
+ shutil.copytree(tempdir_orig, tempdir_copy)
+ # If everything has been closed properly, the original directory
+ # should now be removable
+ shutil.rmtree(tempdir_orig)
+
+ project2 = api.Project(api.Storage.open(tempdir_copy))
+ conf2 = project2.get_configuration("dummy2.confml")
+
+ self.assertEquals(conf.get_name(),conf2.get_name())
+ self.assertEquals(conf2.get_name(),'dummy')
+ self.assertEquals(conf2.meta[0].tag ,'owner')
+ self.assertEquals(conf2.meta[0].value ,'some guy')
+ self.assertEquals(conf.desc,conf2.desc)
+ self.assertEquals(conf.list_configurations(),conf2.list_configurations())
+ project2.close()
+
+ def test_remove_configuration_non_existing(self):
+ try:
+ self.project.remove_configuration("dummystring.txt")
+ self.fail("Removing non existing configuration succeds!")
+ except exceptions.NotFound,e:
+ self.assertTrue(True)
+
+ def test_create_remove_configuration(self):
+ conf = self.project.create_configuration("remove.confml")
+ conf.save()
+ conf.close()
+
+ self.project.remove_configuration("remove.confml")
+ try:
+ conf = self.project.get_configuration("remove.confml")
+ self.fail("Opening of removed configuration succeeds!")
+ except exceptions.NotFound,e:
+ self.assertTrue(True)
+
+ def test_create_configuration_in_sub_configuration(self):
+ fs = api.Storage.open("newproject","w")
+ project = api.Project(fs)
+ conf = project.create_configuration("croot.confml")
+ subconf = conf.create_configuration("test/root.confml")
+ subconf.create_configuration('confml/data.confml')
+ conf.save()
+ self.assertTrue(project.get_storage().is_resource('test/confml/data.confml'))
+ conf = project.get_configuration("croot.confml")
+ subconf = conf.create_configuration("test2\\root.confml")
+ subconf.create_configuration('confml/data.confml')
+ subconf.close()
+ conf.save()
+ self.assertTrue(project.get_storage().is_resource('test2/confml/data.confml'))
+ project.close()
+ shutil.rmtree("newproject")
+
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/core/tests/unittest_configuration_project_on_zipstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_on_zipstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,182 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the CPF configuration
+"""
+import unittest
+import string
+import sys,os, shutil
+import __init__
+
+from cone.public import exceptions, api
+from cone.core import *
+from testautomation.base_testcase import BaseTestCase
+from cone.confml import model
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+temp_dir = os.path.join(ROOT_PATH, "temp/project_on_zipstorage")
+datazip = os.path.join(ROOT_PATH,"testdata/test_project.cpf")
+
+class TestConeProjectOpenZip(unittest.TestCase):
+ def test_open_project(self):
+ fs = api.Storage.open(datazip,"r")
+ p = api.Project(fs)
+ self.assertTrue(p)
+
+ def test_open_project_of_non_storage(self):
+ fs = ""
+ try:
+ p = api.Project(fs)
+ self.fail("Opening on top of non storage succeeds!!")
+ except exceptions.StorageException:
+ self.assertTrue(True)
+
+
+class TestConeProjectMethodsReadZip(unittest.TestCase):
+ def setUp(self):
+ fs = api.Storage.open(datazip,"r")
+ self.project = api.Project(fs)
+
+ def test_list_configurations(self):
+ confs = self.project.list_configurations()
+ self.assertEquals(
+ sorted(confs),
+ ["root1.confml",
+ "root2.confml",
+ "root3.confml",
+ "root4.confml",
+ "root5.confml"])
+
+ def test_get_configuration(self):
+ conf = self.project.get_configuration("/root5.confml")
+ self.assertTrue(conf)
+ self.assertTrue(isinstance(conf,api.ConfigurationProxy))
+
+ def test_get_configuration_non_existing(self):
+ try:
+ conf = self.project.get_configuration("foo")
+ self.fail("Opening non existing configuration succeeds!")
+ except exceptions.NotFound,e:
+ self.assertTrue(True)
+
+ def test_get_configuration_and_list_layers(self):
+ conf = self.project.get_configuration("root5.confml")
+ layers = conf.list_configurations()
+ self.assertEquals(
+ layers,
+ ['Layer1/root.confml',
+ 'Layer2/root.confml',
+ 'Layer3/root.confml',
+ 'Layer4/root.confml',
+ 'Layer5/root.confml'])
+
+ def test_get_configuration_and_get_layer(self):
+ conf = self.project.get_configuration("root5.confml")
+ layer1 = conf.get_configuration('Layer1/root.confml')
+ self.assertTrue(layer1)
+ self.assertTrue(isinstance(layer1,api.ConfigurationProxy))
+
+ def test_get_configuration_and_get_layer_path(self):
+ conf = self.project.get_configuration("root5.confml")
+ layer1 = conf.get_configuration('Layer1/root.confml')
+ self.assertEquals(layer1.get_path(),'Layer1/root.confml')
+
+ def test_get_configuration_and_get_layer_and_get_layer_resources(self):
+ conf = self.project.get_configuration("root5.confml")
+ layer1 = conf.get_configuration('Layer1/root.confml')
+ files = layer1.list_resources()
+ self.assertTrue('Layer1/root.confml' in files)
+ self.assertTrue('Layer1/confml/feature1.confml' in files)
+ self.assertTrue('Layer1/implml/feature1_12341001.crml' in files)
+ self.assertTrue('Layer1/content/default_file.txt' in files)
+
+ def test_get_configuration_and_get_layer_and_get_a_layer_resource(self):
+ conf = self.project.get_configuration("root5.confml")
+ layer1 = conf.get_configuration('Layer1/root.confml')
+ res = layer1.get_resource('implml/feature1_12341001.crml')
+ self.assertTrue(res)
+
+ def test_get_configuration_and_list_all_configuration_resources(self):
+ conf = self.project.get_configuration("root5.confml")
+ resources = conf.list_resources()
+ self.assertTrue('root5.confml' in resources)
+ self.assertTrue('Layer1/root.confml' in resources)
+ self.assertTrue('Layer2/root.confml' in resources)
+ self.assertTrue('Layer3/root.confml' in resources)
+ self.assertTrue('Layer4/root.confml' in resources)
+ self.assertTrue('Layer5/root.confml' in resources)
+ self.assertTrue('Layer1/confml/feature1.confml' in resources)
+ self.assertTrue('Layer1/implml/feature1_12341001.crml' in resources)
+ self.assertTrue('Layer1/content/default_file.txt' in resources)
+ self.assertTrue('Layer2/content/layer2_file.txt' in resources)
+
+class TestConeProjectMethodsWriteZip(BaseTestCase):
+ def setUp(self):
+ if not os.path.exists(temp_dir):
+ os.makedirs(temp_dir)
+
+ def test_create_configuration(self):
+ tempzip = os.path.normpath(os.path.join(temp_dir, "temp1.zip"))
+ self.remove_if_exists(tempzip)
+
+ prj = None
+ conf = None
+ try:
+ prj = api.Project(api.Storage.open(tempzip,"w"))
+ conf = prj.create_configuration("dummy.confml")
+ conf.set_name("dummy")
+ self.assertTrue(conf)
+ self.assertEquals(conf.get_name(),'dummy')
+ self.assertTrue(isinstance(conf,api.Configuration))
+ finally:
+ if conf != None: conf.close()
+ if prj != None: prj.close()
+
+ def test_create_close_open_configuration(self):
+ tempzip_orig = os.path.normpath(os.path.join(temp_dir, "temp2_orig.zip"))
+ tempzip_copy = os.path.normpath(os.path.join(temp_dir, "temp2_copy.zip"))
+ self.remove_if_exists([tempzip_orig, tempzip_copy])
+
+ prj = api.Project(api.Storage.open(tempzip_orig,"w"))
+ conf = prj.create_configuration("dummy2.confml")
+ conf.set_name("dummy")
+ prop1 = model.ConfmlMetaProperty('owner', 'teemu rytkonen', 'http://www.s60.com/xml/confml/2')
+ prop2 = model.ConfmlMetaProperty('purpose', 'for testing', 'http://www.s60.com/xml/confml/2')
+ conf.meta = model.ConfmlMeta([prop1, prop2])
+ conf.desc = "Testing to see a configuration created"
+ conf.create_configuration("test/path/to/somewhere/r.confml")
+ conf.create_configuration("test/path/to/elsewhere/r.confml")
+ conf.save()
+ prj.save()
+ prj.close()
+
+ # Make a copy of the created zip file
+ shutil.copy2(tempzip_orig, tempzip_copy)
+ # If everything has been closed properly, the original zip file
+ # should now be removable
+ os.remove(tempzip_orig)
+
+ # Read back data from the copy
+ prj = api.Project(api.Storage.open(tempzip_copy,"r"))
+ conf2 = prj.get_configuration("dummy2.confml")
+ self.assertEquals(conf.get_name(),conf2.get_name())
+ self.assertEquals(conf.meta,conf2.meta)
+ self.assertEquals(conf.desc,conf2.desc)
+ self.assertEquals(conf.list_configurations(),conf2.list_configurations())
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/nose_unittests.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/nose_unittests.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+[nosetests]
+verbosity=3
+include=unittest
+with-xunit=1
+xunit-file=cone-unittests.xml
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+__all__ = ["api","plugin","exceptions","container","utils","persistence", "settings", "rules"]
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/_etree_wrapper.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/_etree_wrapper.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,245 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from xml.parsers import expat
+
+# Import ElementTree (should always be available)
+try:
+ from elementtree import ElementTree
+except ImportError:
+ from xml.etree import ElementTree
+
+import exceptions
+
+
+class ElementTreeBackendWrapperBase(object):
+ def get_module(self):
+ raise NotImplementedError()
+
+ def get_lineno(self, element):
+ raise NotImplementedError()
+
+class ElementTreeBackendWrapper(ElementTreeBackendWrapperBase):
+
+ class CustomTreeBuilder(ElementTree.TreeBuilder):
+ """
+ Custom TreeBuilder for ElementTree that records line numbers
+ of the elements.
+ """
+ def start(self, tag, attrs):
+ elem = ElementTree.TreeBuilder.start(self, tag, attrs)
+ lineno = self._xmltreebuilder._parser.CurrentLineNumber
+ #print "Tag: %s, line: %r" % (tag, lineno)
+ elem.sourceline = lineno
+ return elem
+
+ def get_module(self):
+ return ElementTree
+
+ def fromstring(self, text):
+ try:
+ treebuilder = self.CustomTreeBuilder()
+ parser = ElementTree.XMLTreeBuilder(target=treebuilder)
+ treebuilder._xmltreebuilder = parser
+ parser.feed(text)
+ return parser.close()
+ except expat.ExpatError, e:
+ raise exceptions.XmlParseError(
+ "XML parse error on line %d: %s" % (e.lineno, e),
+ e.lineno, str(e))
+
+ def tostring(self, etree, encoding=None):
+ return ElementTree.tostring(etree, encoding)
+
+ def get_lineno(self, element):
+ return element.sourceline
+
+
+class CElementTreeBackendWrapper(ElementTreeBackendWrapperBase):
+ def __init__(self):
+ try:
+ from cElementTree import cElementTree
+ except ImportError:
+ from xml.etree import cElementTree
+
+ self.cElementTree = cElementTree
+
+ def get_module(self):
+ return self.cElementTree
+
+ def fromstring(self, text):
+ try:
+ return self.cElementTree.fromstring(text)
+ except SyntaxError, e:
+ # cElementTree raises a SyntaxError, but does not set
+ # its lineno attribute, so look for the line number
+ # in the exception text
+ import re
+ match = re.search(r'line (\d+)\, column \d+$', str(e))
+ if match: lineno = int(match.group(1))
+ else: lineno = None
+
+ raise exceptions.XmlParseError(
+ "XML parse error on line %s: %s" % (lineno, e),
+ lineno, str(e))
+
+ def tostring(self, etree, encoding=None):
+ return self.cElementTree.tostring(etree, encoding)
+
+ def get_lineno(self, element):
+ # cElementTree does not support line numbers
+ return None
+
+
+class LxmlBackendWrapper(ElementTreeBackendWrapperBase):
+
+ def __init__(self):
+ import lxml.etree
+ self.lxml = lxml
+
+ def get_module(self):
+ return self.lxml.etree
+
+ def fromstring(self, text):
+ try:
+ elem = self.lxml.etree.fromstring(text)
+
+ # lxml parses also comments, but ConE does not expect those,
+ # so remove them to prevent any errors on that account
+ def remove_comments(elem):
+ # Find the comments under this element
+ comments = []
+ for x in elem:
+ if isinstance(x, self.lxml.etree._Comment):
+ comments.append(x)
+
+ # Remove them
+ for c in comments:
+ elem.remove(c)
+
+ # Recurse to sub-elements
+ for subelem in elem:
+ remove_comments(subelem)
+
+ remove_comments(elem)
+
+ return elem
+ except self.lxml.etree.XMLSyntaxError, e:
+ raise exceptions.XmlParseError(
+ "XML parse error on line %d: %s" % (e.position[0], e),
+ e.position[0], str(e))
+
+ def tostring(self, etree, encoding=None):
+ return self.lxml.etree.tostring(etree, encoding=encoding)
+
+ def get_lineno(self, element):
+ return element.sourceline
+
+# ============================================================================
+#
+# ============================================================================
+
+class ElementTreeWrapper(object):
+ """
+ ElementTree wrapper class for providing a unified interface to different
+ ElementTree implementations.
+
+ Currently supported are the pure Python ElementTree implementation,
+ cElementTree and lxml.etree
+ """
+ BACKEND_ELEMENT_TREE = 'ElementTree'
+ BACKEND_C_ELEMENT_TREE = 'cElementTree'
+ BACKEND_LXML = 'lxml'
+
+ # Import order for the default back-end. The list is traversed
+ # top-down and the first back-end whose importing is successful is
+ # used as the default back-end
+ DEFAULT_BACKEND_IMPORT_ORDER = [BACKEND_C_ELEMENT_TREE,
+ BACKEND_ELEMENT_TREE]
+
+ _backend_mapping = {BACKEND_ELEMENT_TREE: ElementTreeBackendWrapper,
+ BACKEND_C_ELEMENT_TREE: CElementTreeBackendWrapper,
+ BACKEND_LXML: LxmlBackendWrapper}
+
+ _backend_id = None
+ _backend_wrapper = None
+
+ def get_backend_id(self):
+ """
+ Return the ID of the currently used ElementTree back-end.
+ """
+ # Make sure that the default back-end is set, so _backend_id
+ # will not be None
+ self._get_backend()
+ assert self._backend_id is not None
+ return self._backend_id
+
+ def set_backend_id(self, backend_id):
+ """
+ Set the used ElementTree back-end by back-end ID.
+ """
+ if backend_id not in self._backend_mapping:
+ raise ValueError("Invalid ElementTree back-end ID: %r" % backend_id)
+
+ if backend_id == self._backend_id:
+ return
+
+ backend_wrapper_class = self._backend_mapping[backend_id]
+ self._backend_wrapper = backend_wrapper_class()
+ self._backend_id = backend_id
+
+ def _get_backend(self):
+ """
+ Return the currently set ElementTree back-end wrapper object.
+ """
+ if self._backend_wrapper is None:
+ # Back-end not set, so set the default back-end.
+ # The default is the C version of ElementTree, but if that
+ # is not available, the pure Python version is used
+ for backend_id in self.DEFAULT_BACKEND_IMPORT_ORDER:
+ try:
+ self.set_backend_id(backend_id)
+ except ImportError:
+ pass
+
+ if self._backend_wrapper is None:
+ raise RuntimeError("Failed to set any ElementTree backend! Tried these: %r" % self.DEFAULT_BACKEND_IMPORT_ORDER)
+
+ return self._backend_wrapper
+
+ def get_lineno(self, element):
+ """
+ Return the source line number of the given XML element.
+
+ Note that for the cElementTree parser this will always return
+ None, since that parser does not support line numbers.
+ """
+ return self._get_backend().get_lineno(element)
+
+ def __getattribute__(self, attrname):
+ try:
+ # Try to get the attribute from this object (the top-level wrapper)
+ return object.__getattribute__(self, attrname)
+ except AttributeError:
+ # If not overridden here, try to get it from the back-end wrapper
+ backend = self._get_backend()
+ try:
+ return getattr(backend, attrname)
+ except AttributeError:
+ # Last resort: try to get it from the module
+ # the back-end wrapper wraps
+ backend_module = backend.get_module()
+ return getattr(backend_module, attrname)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/_plugin_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/_plugin_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,568 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import copy
+import logging
+import plugin, exceptions, api, utils
+import cone.confml.model
+
+log = logging.getLogger('cone')
+
+# The XML namespace for common ImplML definitions
+COMMON_IMPLML_NAMESPACE = "http://www.symbianfoundation.org/xml/implml/1"
+
+# Name of the marker variable used to mark a feature as a temporary
+# feature
+TEMP_FEATURE_MARKER_VARNAME = '__plugin_temp_feature_marker'
+
+class TempVariableDefinition(object):
+ """
+ Class representing a temporary variable definition in an implementation file.
+ """
+
+ def __init__(self, ref, type, value):
+ self.ref = ref
+ self.type = type
+ self.value = value
+
+ def create_feature(self, config):
+ """
+ Add a feature based on this temp feature definition to the given configuration.
+ """
+ if '.' in self.ref:
+ pos = self.ref.rfind('.')
+ ref = self.ref[pos + 1:]
+ namespace = self.ref[:pos]
+ else:
+ ref = self.ref
+ namespace = ''
+
+ mapping = {'string' : cone.confml.model.ConfmlStringSetting,
+ 'int' : cone.confml.model.ConfmlIntSetting,
+ 'real' : cone.confml.model.ConfmlRealSetting,
+ 'boolean': cone.confml.model.ConfmlBooleanSetting}
+ feature = mapping[self.type](ref)
+ setattr(feature, TEMP_FEATURE_MARKER_VARNAME, True)
+ config.add_feature(feature, namespace)
+
+ value = utils.expand_refs_by_default_view(self.value, config.get_default_view())
+ config.add_data(api.Data(fqr=self.ref, value=value))
+
+ def __eq__(self, other):
+ if type(self) is type(other):
+ for varname in ('ref', 'type', 'value'):
+ if getattr(self, varname) != getattr(other, varname):
+ return False
+ return True
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ return "TempFeatureDefinition(ref=%r, type=%r, value=%r)" % (self.ref, self.type, self.value)
+
+class TempVariableSequenceDefinition(object):
+ """
+ Class representing a temporary variable sequence definition in an implementation file.
+ """
+
+ def __init__(self, ref, sub_items):
+ self.ref = ref
+ self.sub_items = sub_items
+
+ def create_feature(self, config):
+ if '.' in self.ref:
+ pos = self.ref.rfind('.')
+ ref = self.ref[pos + 1:]
+ namespace = self.ref[:pos]
+ else:
+ ref = self.ref
+ namespace = ''
+
+ # Creature the sequence feature
+ seq_fea = api.FeatureSequence(ref)
+ setattr(seq_fea, TEMP_FEATURE_MARKER_VARNAME, True)
+ config.add_feature(seq_fea, namespace)
+
+ # Create the sub-features
+ mapping = {'string' : cone.confml.model.ConfmlStringSetting,
+ 'int' : cone.confml.model.ConfmlIntSetting,
+ 'real' : cone.confml.model.ConfmlRealSetting,
+ 'boolean': cone.confml.model.ConfmlBooleanSetting}
+ sub_features = []
+ for sub_item in self.sub_items:
+ sub_feature = mapping[sub_item[1]](sub_item[0])
+ seq_fea.add_feature(sub_feature)
+
+ def __eq__(self, other):
+ if type(self) is type(other):
+ return self.ref == other.ref and self.sub_items == other.sub_items
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ return "TempSeqFeatureDefinition(ref=%r, sub_items=%r)" % (self.ref, self.sub_items)
+
+class SettingRefsOverride(object):
+ """
+ Class representing a setting reference override for an implementation.
+ """
+ def __init__(self, refs=None):
+ """
+ @param refs: The reference overrides, can be a list of references or None.
+ """
+ self.refs = refs
+
+ def get_refs(self):
+ return self.refs
+
+ def __eq__(self, other):
+ if type(self) is type(other):
+ return self.refs == other.refs
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ return "SettingRefsOverride(refs=%r)" % self.refs
+
+class CommonImplmlData(object):
+ """
+ Class representing the common ImplML namespace data read from
+ an XML element.
+ """
+
+ def __init__(self):
+ self.phase = None
+ self.tags = None
+ self.tempvar_defs = []
+ self.setting_refs_override = None
+ self.output_root_dir = None
+ self.output_sub_dir = None
+
+ def apply(self, impl):
+ """
+ Apply the data on the given implementation instance.
+ """
+ if self.phase:
+ impl.set_invocation_phase(self.phase)
+ if self.tags:
+ impl.set_tags(self.tags)
+ if self.setting_refs_override:
+ # Override the get_refs() method of the implementation
+ impl.get_refs = self.setting_refs_override.get_refs
+ # Override also the has_ref() method in case it is overridden
+ # in the implementation sub-class
+ impl.has_ref = lambda refs: plugin.ImplBase.has_ref(impl, refs)
+ if self.output_root_dir:
+ impl.set_output_root_override(self.output_root_dir)
+ if self.output_sub_dir:
+ impl.output_subdir = self.output_sub_dir
+
+ def extend(self, other):
+ """
+ Extend this object with the contents of another CommonImplmlData object.
+ """
+ if other.phase:
+ self.phase = other.phase
+ if other.tags:
+ self.tags = other.tags
+ self.tempvar_defs.extend(other.tempvar_defs)
+ if other.setting_refs_override:
+ self.setting_refs_override = other.setting_refs_override
+ if other.output_root_dir:
+ self.output_root_dir = other.output_root_dir
+ if other.output_sub_dir:
+ self.output_sub_dir = other.output_sub_dir
+
+ def copy(self):
+ result = CommonImplmlData()
+ result.phase = self.phase
+ if result.tags is not None:
+ result.tags = self.tags.copy()
+ result.tempvar_defs = list(self.tempvar_defs)
+ result.setting_refs_override = copy.deepcopy(self.setting_refs_override)
+ result.output_root_dir = self.output_root_dir
+ result.output_sub_dir = self.output_sub_dir
+ return result
+
+ def __eq__(self, other):
+ if type(self) is type(other):
+ for varname in ('phase', 'tags', 'tempvar_defs', 'setting_refs_override', 'output_root_dir', 'output_sub_dir'):
+ if getattr(self, varname) != getattr(other, varname):
+ return False
+ return True
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ return "CommonImplmlData(phase=%r, tags=%r, tempvar_defs=%r, setting_refs_override=%r, output_root_dir=%r, output_sub_dir=%r)" \
+ % (self.phase,
+ self.tags,
+ self.tempvar_defs,
+ self.setting_refs_override,
+ self.output_root_dir,
+ self.output_sub_dir)
+
+class ImplReader(object):
+ """
+ Internal reader class for reading implementations from a file in a configuration.
+ """
+
+ # The reader class list loaded using ImplFactory
+ __loaded_reader_classes = None
+ __reader_classes = None
+ __supported_file_extensions = None
+ __ignored_namespaces = None
+
+ def __init__(self, resource_ref, configuration):
+ self.resource_ref = resource_ref
+ self.configuration = configuration
+
+ @classmethod
+ def _load_data_from_plugins(cls):
+ """
+ Load all data needed for implementation parsing from the plug-ins.
+
+ The actual loading is only done the first time this method is called.
+ """
+ # Load the data only if the reader class list has not been loaded
+ # yet or it has changed
+ loaded_reader_classes = plugin.ImplFactory.get_reader_classes()
+ if cls.__loaded_reader_classes is loaded_reader_classes:
+ return
+
+ reader_classes = [plugin.ReaderBase]
+ reader_classes.extend(loaded_reader_classes)
+
+ cls.__reader_classes = {}
+ cls.__ignored_namespaces = []
+ cls.__supported_file_extensions = []
+
+ for rc in reader_classes:
+ # Reader class
+ ns = rc.NAMESPACE
+ if ns is not None:
+ if ns in cls.__reader_classes:
+ raise RuntimeError("Multiple reader classes registered for ImplML namespace '%s': at least %s and %s"\
+ % (ns, rc, cls.__reader_classes[ns]))
+ cls.__reader_classes[ns] = rc
+
+ # Ignored namespaces
+ for ns in rc.IGNORED_NAMESPACES:
+ if ns not in cls.__ignored_namespaces:
+ cls.__ignored_namespaces.append(ns)
+
+ # Supported file extensions
+ for fe in rc.FILE_EXTENSIONS:
+ fe = fe.lower()
+ if fe not in cls.__supported_file_extensions:
+ cls.__supported_file_extensions.append(fe)
+
+ cls.__loaded_reader_classes = loaded_reader_classes
+
+ @classmethod
+ def _get_namespaces(cls, etree):
+ """
+ Return a list of XML namespaces in the given element tree.
+ """
+ namespaces = []
+ namespaces.append(utils.xml.split_tag_namespace(etree.tag)[0])
+ for elem in etree:
+ ns = utils.xml.split_tag_namespace(elem.tag)[0]
+ if ns not in namespaces:
+ namespaces.append(ns)
+ return filter(lambda ns: ns is not None, namespaces)
+
+ def _read_impls_from_file_root_element(self, root, namespaces):
+ impls = []
+ reader_classes = self.get_reader_classes()
+
+ # Go through the list of XML namespaces encountered in the
+ # file and read an implementation using the corresponding
+ # reader for each namespace
+ impl_count = 0
+ common_data = CommonImplmlDataReader.read_data(root)
+ for ns in namespaces:
+ if ns not in reader_classes: continue
+
+ rc = reader_classes[ns]
+ impl = self._read_impl(rc, root)
+ if impl:
+ impl.index = impl_count
+ impl_count += 1
+ if common_data: common_data.apply(impl)
+ impls.append(impl)
+
+ # Add temp feature definitions to the first implementation
+ if common_data and impls:
+ impls[0]._tempvar_defs.extend(common_data.tempvar_defs)
+ return impls
+
+ def _read_impls_from_file_sub_elements(self, root):
+ impls = []
+
+ # Collect common ImplML namespace data
+ common_data = CommonImplmlData()
+ for elem in root:
+ ns = utils.xml.split_tag_namespace(elem.tag)[0]
+ if ns == COMMON_IMPLML_NAMESPACE:
+ cd = CommonImplmlDataReader.read_data(elem)
+ if cd: common_data.extend(cd)
+
+ # Go through all sub-elements and read an implementation instance
+ # from each if possible
+ impl_count = 0
+ reader_classes = self.get_reader_classes()
+ for elem in root:
+ ns = utils.xml.split_tag_namespace(elem.tag)[0]
+ if ns != COMMON_IMPLML_NAMESPACE and ns in reader_classes:
+ reader_class = reader_classes[ns]
+ impl = self._read_impl(reader_class, elem)
+ if impl:
+ cd = CommonImplmlDataReader.read_data(elem)
+ if cd is not None:
+ impl._tempvar_defs.extend(cd.tempvar_defs)
+ data = common_data.copy()
+ data.extend(cd)
+ data.apply(impl)
+ else:
+ common_data.apply(impl)
+
+ impl.index = impl_count
+ impl_count += 1
+ impls.append(impl)
+
+ # Add temporary feature definitions to the first implementation instance
+ if impls:
+ impls[0]._tempvar_defs = common_data.tempvar_defs + impls[0]._tempvar_defs
+
+ return impls
+
+ def _read_impl(self, reader_class, elem):
+ """
+ Read an implementation with the given reader class from the given element.
+
+ If an exception is raised during reading, the exception is logged
+ and None returned.
+
+ @return: The read implementation or None.
+ """
+ try:
+ return reader_class.read_impl(self.resource_ref, self.configuration, elem)
+ except exceptions.ParseError, e:
+ log.error("Error reading implementation '%s': %s", (self.resource_ref, e))
+ except Exception, e:
+ utils.log_exception(log, e)
+
+ return None
+
+ @classmethod
+ def get_reader_classes(cls):
+ """
+ Return a dictionary of all possible implementation reader classes.
+
+ Dictionary key is the XML namespace and the value is the corresponding
+ reader class.
+ """
+ cls._load_data_from_plugins()
+ return cls.__reader_classes
+
+ @classmethod
+ def get_supported_file_extensions(cls):
+ """
+ Return a list of all supported implementation file extensions.
+ """
+ cls._load_data_from_plugins()
+ return cls.__supported_file_extensions
+
+ @classmethod
+ def get_ignored_namespaces(cls):
+ """
+ Return a list of all ignored XML namespaces.
+ """
+ cls._load_data_from_plugins()
+ return cls.__ignored_namespaces
+
+ def read_implementations(self):
+ try:
+ root = plugin.ReaderBase._read_xml_doc_from_resource(self.resource_ref, self.configuration)
+ return self.read_implementation(root)
+ except exceptions.ParseError, e:
+ # Invalid XML data in the file
+ log.error(e)
+ return []
+
+ def read_implementation(self, xmlroot):
+ root = xmlroot
+
+ # Check if the implementations should all be read from the
+ # document root, or each from its own sub-element under the root
+ read_from_root = False
+ ns = utils.xml.split_tag_namespace(root.tag)[0]
+ if ns: read_from_root = True
+
+ # Collect namespaces from the file and check that all are supported or ignored
+ namespaces = self._get_namespaces(root)
+ for ns in namespaces:
+ if ns != COMMON_IMPLML_NAMESPACE \
+ and ns not in self.get_reader_classes() \
+ and ns not in self.get_ignored_namespaces():
+ log.error("Unsupported XML namespace '%s' in file '%s'" % (ns, self.resource_ref))
+ return []
+
+ if read_from_root:
+ impls = self._read_impls_from_file_root_element(root, namespaces)
+ else:
+ impls = self._read_impls_from_file_sub_elements(root)
+ return impls
+
+
+class CommonImplmlDataReader(object):
+ """
+ Internal reader class for reading common ImplML namespace data from and element.
+ """
+
+ VALID_PHASES = ('pre', 'normal', 'post')
+ VALID_TYPES = ('string', 'int', 'real', 'boolean')
+
+ @classmethod
+ def read_data(cls, etree):
+ """
+ Read common ImplML data from the given XML element.
+ @return: A CommonImplmlData instance or None if no common namespace
+ elements were found.
+ """
+ result = CommonImplmlData()
+
+ reader_methods = {'phase' : cls._read_phase,
+ 'tag' : cls._read_tag,
+ 'tempVariable' : cls._read_tempvar,
+ 'tempVariableSequence' : cls._read_tempvarseq,
+ 'settingRefsOverride' : cls._read_setting_refs_override,
+ 'outputRootDir' : cls._read_output_root_dir,
+ 'outputSubDir' : cls._read_output_sub_dir}
+
+ found = False
+ for elem in etree:
+ ns, tag = utils.xml.split_tag_namespace(elem.tag)
+ if ns != COMMON_IMPLML_NAMESPACE: continue
+ if tag not in reader_methods: continue
+
+ reader_methods[tag](elem, result)
+ found = True
+
+ if found: return result
+ else: return None
+
+ @classmethod
+ def _read_phase(cls, elem, result):
+ phase = elem.get('name')
+ if phase is None:
+ cls._raise_missing_attr(elem, 'name')
+ if phase not in cls.VALID_PHASES:
+ raise exceptions.ParseError("Invalid invocation phase '%s' defined." % phase)
+
+ result.phase = phase
+
+ @classmethod
+ def _read_tag(cls, elem, result):
+ name = elem.get('name')
+ value = elem.get('value')
+ if name is not None:
+ if result.tags is None: result.tags = {}
+ if name not in result.tags: result.tags[name] = []
+ result.tags[name].append(value)
+
+ @classmethod
+ def _read_tempvar(cls, elem, result):
+ ref = elem.get('ref')
+ type = elem.get('type', 'string')
+ value = elem.get('value', '')
+
+ if ref is None:
+ cls._raise_missing_attr(elem, 'ref')
+ if type not in cls.VALID_TYPES:
+ cls._raise_invalid_type(ref, type)
+
+ result.tempvar_defs.append(TempVariableDefinition(ref, type, value))
+
+ @classmethod
+ def _read_tempvarseq(cls, elem, result):
+ ref = elem.get('ref')
+ if ref is None:
+ cls._raise_missing_attr(elem, 'ref')
+
+ sub_items = []
+ for sub_elem in elem.findall('{%s}tempVariable' % COMMON_IMPLML_NAMESPACE):
+ sub_ref = sub_elem.get('ref')
+ sub_type = sub_elem.get('type', 'string')
+
+ if sub_ref is None:
+ cls._raise_missing_attr(sub_elem, 'ref')
+ if sub_type not in cls.VALID_TYPES:
+ cls._raise_invalid_type(sub_ref, sub_type)
+
+ sub_items.append((sub_ref, sub_type))
+
+ if not sub_items:
+ raise exceptions.ParseError("Temporary variable sequence '%s' does not have any sub-items" % ref)
+
+ result.tempvar_defs.append(TempVariableSequenceDefinition(ref, sub_items))
+
+ @classmethod
+ def _read_setting_refs_override(cls, elem, result):
+ if elem.get('refsIrrelevant', 'false').lower() in ('1', 'true'):
+ refs = None
+ else:
+ refs = []
+ for sub_elem in elem.findall('{%s}settingRef' % COMMON_IMPLML_NAMESPACE):
+ ref = sub_elem.get('value')
+
+ if ref is None:
+ cls._raise_missing_attr(sub_elem, 'value')
+
+ refs.append(ref)
+
+ result.setting_refs_override = SettingRefsOverride(refs)
+
+ @classmethod
+ def _read_output_root_dir(cls, elem, result):
+ value = elem.get('value')
+ if value: result.output_root_dir = value
+
+ @classmethod
+ def _read_output_sub_dir(cls, elem, result):
+ value = elem.get('value')
+ if value: result.output_sub_dir = value
+
+ @classmethod
+ def _raise_missing_attr(cls, elem, attrname):
+ raise exceptions.ParseError("XML element %s does not contain the mandatory '%s' attribute." % (elem.tag, attrname))
+
+ @classmethod
+ def _raise_invalid_type(cls, ref, type):
+ raise exceptions.ParseError("Invalid feature type '%s' specified for temporary ConfML feature '%s'." % (type, ref))
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/api.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/api.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3020 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+"""
+Cone public API.
+The core interface to the ConE functionality.
+"""
+
+import os
+import re
+import sys
+import logging
+import copy
+import sets
+
+import exceptions, utils, container, mapping
+
+class Base(container.ObjectContainer):
+ """
+ The Base class is intended for capturing same kind of naming scheme.
+ """
+
+
+ def __init__(self, ref="", **kwargs):
+ if len(utils.dottedref.split_ref(ref)) > 1:
+ raise exceptions.InvalidRef("Invalid reference for Base object %s!" % ref)
+ self.ref = ref
+ container.ObjectContainer.__init__(self, ref)
+ for arg in kwargs.keys():
+ if kwargs.get(arg) != None:
+ setattr(self, arg, kwargs.get(arg))
+
+ def __repr__(self):
+ dict = self._dict()
+ return "%s(%s)" % (self.__class__.__name__, dict)
+
+ def _get_mapper(self,modelname):
+ """
+ Return a instance of appropriate mapper for given model.
+ """
+ return mapping.BaseMapper()
+
+ def _compare(self, other, dict_keys=None):
+ """
+ Compare the attributes of elements
+ """
+ if isinstance(other, Base):
+ keys = dict_keys or self._dict().keys()
+ for key in keys:
+ self_attr = None
+ other_attr = None
+ try:
+ self_attr = getattr(self, key)
+ other_attr = getattr(other, key)
+ except AttributeError:
+ # If the attribute is not found from either elements
+ # ignore it entirely
+ if self_attr == None and other_attr == None:
+ continue
+ if self_attr != other_attr:
+ return False
+ # If all given keys match report this as as similar element
+ return True
+ else:
+ return False
+
+ def _clone(self, **kwargs):
+ """
+ A generic implementation for cloning the object.
+ Copies all (public) members in dictionary.
+ To clone objects recursively set the recursion level with recursion param.
+ @param recursion: Boolean to define recursion on or off
+ @param recursion_depth: positive integer to define recursion depth. default is -1 which will
+ perform recursion to all objects.
+ """
+ dict = self._dict()
+ if kwargs.get('class_instance'):
+ class_instance = kwargs.get('class_instance')
+ del kwargs['class_instance']
+ else:
+ class_instance = self.__class__
+ obj = class_instance(**dict)
+ # Remove all children created at the construction phase
+ # This is needed when the recursion adds children to the object so that there are not duplicates
+ obj._order = []
+ obj._children = {}
+
+ # handle the recursion argument
+ recursion = kwargs.get('recursion', False)
+ if recursion:
+ recursion_depth = kwargs.get('recursion_depth', -1)
+ if recursion_depth < 0 or recursion_depth > 0:
+ # decrease the recursion
+ kwargs['recursion_depth'] = recursion_depth - 1
+ for child in self._objects():
+ obj._add(child._clone(**kwargs), container.APPEND)
+ return obj
+
+ def _dict(self):
+ """
+ Return the public variables in a dictionary
+ """
+ dict = {}
+ for key in self.__dict__.keys():
+ if key.startswith('_'):
+ continue
+ else:
+ dict[key] = self.__dict__[key]
+ return dict
+
+ def _default_object(self, name):
+ return Base(name)
+
+ @property
+ def fqr(self):
+ """
+ Return a Fully Qualified Ref, which is the full name of the reference.
+ Joins the namespace and ref to one string.
+ @return: A string
+ """
+ return utils.dottedref.join_refs([self.namespace, self.get_ref()])
+
+ @property
+ def namespace(self):
+ """
+ @return: The namespace of the object.
+ """
+ containerpath = ""
+ path = ""
+ parentcontainer = self.find_parent(container=True)
+ parent = self.find_parent(type=Base)
+ paths = []
+ while parent and parent != parentcontainer:
+ """ Skip the element if it is supposed to be hidden. Begins with _. """
+ if not parent.get_ref().startswith('_'):
+ paths.append(parent.get_ref())
+ parent = parent._get_parent()
+ if parentcontainer:
+ paths.append(parentcontainer.namespace)
+ paths.reverse()
+ return utils.dottedref.join_refs(paths)
+
+ def get_fullref(self):
+ """
+ Return a full reference, reference including a
+ possible index of the object in list.
+ e.g. ref can be bar[1] or just the normal bar.
+
+ @return: The full reference of the object.
+ """
+ if self.parent and utils.is_list(self.parent._get(self.ref)):
+ return "%s[%s]" % (self.ref, self.get_index())
+ else:
+ return self.ref
+
+ def get_fullfqr(self):
+ """
+ Return a full reference, reference including a
+ possible index of the object in list.
+ ref and adds index.
+ @return: A string
+ """
+ return utils.dottedref.join_refs([self.get_fullnamespace(), self.get_fullref()])
+
+ def get_fullnamespace(self):
+ """
+ @return: The full namespace of the object with possible indexes of the parent objects
+ """
+ containerpath = ""
+ path = ""
+ parentcontainer = self.find_parent(container=True)
+ parent = self.find_parent(type=Base)
+ paths = []
+ while parent and parent != parentcontainer:
+ paths.append(parent.get_fullref())
+ parent = parent.parent
+ if parentcontainer:
+ paths.append(parentcontainer.namespace)
+ paths.reverse()
+ return utils.dottedref.join_refs(paths)
+
+ def get_storage(self):
+ """
+ Get the root storage from the root object.
+ """
+ if self._find_parent():
+ return self._find_parent().get_storage()
+ else:
+ raise exceptions.StorageException("Storage is not found from root!")
+
+ def get_project(self):
+ """
+ Get the root project from the root object.
+ """
+ if isinstance(self, Project):
+ return self
+ elif self._find_parent():
+ return self._find_parent().get_project()
+ else:
+ raise exceptions.NotFound("Project not found!!")
+
+ def get_default_view(self):
+ """
+ Get the default view from the root object.
+ """
+ try:
+ return self._find_parent().get_default_view()
+ except exceptions.NotFound:
+ raise exceptions.NotFound("Default View is not found! No root configuration?")
+
+ def get_root(self):
+ """
+ Get the root object
+ """
+ try:
+ return self._find_parent().get_root()
+ except exceptions.NotFound:
+ return self
+
+ def get_root_configuration(self):
+ """
+ Get the root object
+ """
+ if self.find_parent(type=Configuration):
+ return self.find_parent(type=Configuration).get_root_configuration()
+ elif isinstance(self, Configuration):
+ return self
+ else:
+ return None
+
+ def get_index(self):
+ """
+ @return : the index of the data element for sequential data defined inside the same configuration.
+ 0 for normal data.
+ """
+ # Get the list of items from parent which contains this element and ask my own index
+ # Make sure that the returned element is a list with get_list
+ selflist = utils.get_list(self._get_parent()._get(self.get_ref()))
+ return selflist.index(self)
+
+ def find_parent(self, **kwargs):
+ """
+ find the closest parent object of given type.
+ e.g. find_parent(type=Configuration) returns the closest parent
+ Configuration parent instance
+ @param type: class definitiob
+ """
+ type = kwargs.get('type', None)
+ container = kwargs.get('container', False)
+ try:
+ parent = self._find_parent()
+ if type and isinstance(parent, type):
+ return parent
+ elif container and hasattr(parent, 'container'):
+ return parent
+ else:
+ return parent.find_parent(**kwargs)
+ except exceptions.NotFound:
+ return None
+
+ def add(self, child, policy=container.REPLACE):
+ """
+ A generic add function to add child objects. The function is intended to act as
+ proxy function that call the correct add function based on the child objects class.
+
+ Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+ @param child: the child object to add
+ @raise IncorrectClassError: if the given class cannot be added to this object.
+ """
+ raise exceptions.NotSupportedException("Cannot add %s object to %s" % (child, self))
+
+ def get_elem(self, fqr):
+ """
+ A generic get function to get child objects and members. The function uses getattr
+ to traverse downwards the the object tree. The returned object is the final object or attribute
+ if it is found. Raises AttributeError if the child is not found.
+
+ Example: obj.get('test.bar'), returns child obj.test.bar
+ @param fqr: the fully qualified ref to the object
+ @raise AttributeError: if the given ref is not found.
+ """
+ return None
+
+
+class Project(Base):
+ """
+ A project is a container that can hold several Configuration objects.
+ """
+
+ def __init__(self, storage, **kwargs):
+ """
+ Project constructor
+ """
+ Base.__init__(self, "")
+ """ Try to set the model and tet the actual configuration class """
+ try:
+ self._model = storage.persistentmodule.MODEL
+ except AttributeError:
+ self._model = None
+
+ self.set_storage(storage)
+ self.update()
+ self.loaded = {}
+
+ def __add_loaded__(self, ref, obj):
+ """
+ Add the object to loaded
+ """
+ self.loaded[ref] = {'counter': 0, 'obj': obj}
+
+ def __get_loaded__(self, ref):
+ """
+ Get a loaded object if it is existing and increase the reference counter
+ @param ref:
+ @return: The loaded object if it exists. None if it does not.
+ """
+ if self.loaded.has_key(ref):
+ return self.loaded[ref]['obj']
+ else:
+ return None
+
+ def __loaded__(self, ref):
+ """
+ Get a loaded object if it is existing and increase the reference counter
+ @param ref:
+ @return: The loaded object if it exists. None if it does not.
+ """
+ if self.loaded.has_key(ref):
+ self.loaded[ref]['counter'] += 1
+ else:
+ raise exceptions.NotFound("ref %s is not found from loaded!" % ref)
+
+ def __unloaded__(self, ref):
+ """
+ returns True when the reference count is zero and object can be released.
+ """
+ if self.loaded.has_key(ref):
+ self.loaded[ref]['counter'] -= 1
+ if self.loaded[ref]['counter'] == 0:
+ del self.loaded[ref]
+ return True
+ else:
+ return False
+ else:
+ return True
+
+ def _supported_type(self, obj):
+ if isinstance(obj, Configuration) \
+ or isinstance(obj, ConfigurationProxy):
+ return True
+ else:
+ return False
+
+
+ def update(self):
+ """
+ update the root confml files as configurations
+ """
+ root_confmls = self.get_storage().list_resources(".")
+ root_confmls = utils.resourceref.filter_resources(root_confmls, "\.confml")
+ for rootml in root_confmls:
+ self._add(ConfigurationProxy(rootml))
+
+ def get_storage(self):
+ """
+ Get the Storage instance of this Project.
+ """
+ return self.storage
+
+ def set_storage(self, storage):
+ """
+ Set the Storage instance of this Project.
+ """
+ if isinstance(storage, Storage):
+ self.storage = storage
+ else:
+ raise exceptions.StorageException("The given storage is not a instance of Storage!")
+
+ def list_configurations(self, filter_or_filters=None):
+ """
+ List the direct child objects of the project (Root configurations)
+ @param filter_or_filters: A regular expression or list of regular expressions
+ used for filtering the configuration paths. If None, all configurations are
+ returned.
+ @return: a list for configuration file paths
+ """
+ filters = None
+ if isinstance(filter_or_filters, basestring): filters = [filter_or_filters]
+ elif filter_or_filters is not None: filters = filter_or_filters
+
+ configs = [obj.get_path() for obj in self._objects()]
+
+ if filters is not None:
+ result = []
+ for config in configs:
+ for filter in filters:
+ if re.match(filter, config) is not None:
+ result.append(config)
+ break
+ return result
+ else:
+ return configs
+
+ def list_all_configurations(self):
+ """
+ List all configuration objects of the project (all configurations)
+ @return: a list for configuration file paths
+ """
+ return [obj.get_path() for obj in self._traverse(type=(Configuration, ConfigurationProxy))]
+
+ def get_configuration(self, path):
+ """
+ Get a configuration object from the given path
+ @param path: path to configuration
+ @return: a instance of Configuration.
+ """
+ # Load the configuration object if it is not already loaded
+ try:
+ return self._get(utils.resourceref.to_objref(utils.resourceref.norm(path)))
+ except exceptions.NotFound, e:
+ if self.storage.is_resource(utils.resourceref.norm(path)):
+ proxy = ConfigurationProxy(utils.resourceref.norm(path))
+ proxy._set_parent(self)
+ return proxy
+ else:
+ raise e
+
+ def is_configuration(self, path):
+ """
+ Return true if the given path is a configuration object in this Project.
+ @param path: path to configuration
+ @return: Boolean return value.
+ """
+ # Changed from list_all_configurations to list_configurations
+ # (list_all_configurations causes a insane performance problem with _traverse)
+ return path in self.list_configurations()
+
+ def add_configuration(self, config):
+ """
+ Add a Configuration object to this project
+ """
+ if isinstance(config, Configuration):
+ if self.is_configuration(config.get_path()):
+ raise exceptions.AlreadyExists("%s" % config.get_path())
+ self._add(config)
+ self.__add_loaded__(config.get_path(), config)
+ self.__loaded__(config.get_path())
+ else:
+ raise exceptions.IncorrectClassError("Only Configuration instance can be added to Project!")
+
+ def create_configuration(self, path, namespace=""):
+ """
+ Create a Configuration object to this project
+ """
+ config = self.get_configuration_class()(utils.resourceref.norm(path), namespace=namespace)
+ self.add_configuration(config)
+ return config
+
+ def remove_configuration(self, path):
+ """
+ Remove a Configuration by its reference
+ """
+ # remove configuration as an object and try to remove it from the storage
+ self._remove(utils.resourceref.to_objref(path))
+ try:
+ self.storage.delete_resource(path)
+ except exceptions.NotSupportedException:
+ pass
+ return
+
+ def import_configuration(self, configuration):
+ """
+ Import a configuration object from another storage
+ """
+ self.storage.import_resources(configuration.list_resources(), configuration.get_storage())
+ return
+
+ def export_configuration(self, configuration, export_storage, empty_folders=False):
+ """
+ Export a configuration object to another storage
+ """
+ # First clone the configuration and then import the rest of the configuration resources
+ if isinstance(configuration, ConfigurationProxy):
+ configuration = configuration._get_obj()
+
+ export_storage.unload(configuration.get_full_path(),configuration)
+ for child in configuration._traverse(type=Configuration):
+ export_storage.unload(child.get_full_path(),child)
+
+ #If the configuration is not in the root of the project adding the path
+ #to final exporting source path.
+ #l = []
+ cpath = utils.resourceref.get_path(configuration.get_path())
+ resr = [utils.resourceref.join_refs([cpath,related]) \
+ for related in configuration.get_layer().list_all_related(empty_folders)]
+ self.storage.export_resources(resr ,export_storage, empty_folders)
+ return
+
+ def get_configuration_class(self):
+ """
+ return the default configuration class that is used with the model.
+ """
+ return utils.get_class(self._model, Configuration)
+
+ def save(self):
+ """
+ Save the object to the permanent Storage object. Calls the save operation for
+ all the children and also for the Storage.
+ """
+ for child in self._objects():
+ if isinstance(child, (Configuration, ConfigurationProxy)):
+ child.save()
+ self.storage.save()
+
+ def close(self):
+ """
+ Close the Project.
+ """
+ for child in self._objects():
+ if isinstance(child, (Configuration, ConfigurationProxy)):
+ child.close()
+ self.storage.close()
+
+ def load(self, path):
+ """
+ Load an object from a reference. The given reference is loaded once from storage
+ and stored as a loaded object to the Project. Sequential loads to the same ref will
+ return the same object.
+ @param path: The reference where to load the object
+ @raise StorageException: if the given object cannot be loaded as an
+ object from this storage
+ """
+ if not self.__get_loaded__(path):
+ configuration = self.get_storage().load(path)
+ if configuration.get_ref() == 'unknown':
+ configuration.set_ref(utils.resourceref.to_dref(path))
+ self.__add_loaded__(path, configuration)
+ """ increase the ref counter """
+ self.__loaded__(path)
+ return self.__get_loaded__(path)
+
+ def unload(self, path, object):
+ """
+ Release the given ref, which decreases the reference counter of the given ref.
+ @param path: The reference where to store the object
+ @param object: The object instance to dump
+ @raise StorageException: if the given object cannot be dumped to this storage
+ """
+ if self.__unloaded__(path):
+ self.get_storage().unload(path, object)
+
+ def get_path(self):
+ """
+ Return the path of the project, which is always root
+ """
+ return ""
+
+
+class CompositeConfiguration(Base):
+ """
+ A base class for composite Configuration objects.
+ """
+ def __init__(self, ref="", **kwargs):
+# self.meta = {}
+# self.desc = ""
+ super(CompositeConfiguration, self).__init__(ref, **kwargs)
+ self.container = True
+
+ def add_configuration(self, config):
+ """
+ Add an existing Configuration to this configuration
+ @param config: A Configuration instance:
+ @return: None
+ """
+ """
+ Merge the default view features from added config to this configs _default_view.
+ """
+ self._add(config)
+
+ def include_configuration(self, configref):
+ """
+ Add an existing Configuration to this configuration by its resource reference
+ @param config: A Configuration instance:
+ @return: None
+ """
+ # add the configuration load proxy to this configuration instead
+ # adding the configuration directly
+ self._add(ConfigurationProxy(configref))
+
+ def create_configuration(self, path):
+ """
+ Create a new configuration by its name to the Configuration.
+ 1. Create new Configuration object
+ 2. Create new ConfigurationProxy
+ 3. Add proxy to this object
+ 4. Set proxy to point to the created Configuration object
+ @param path: The reference of the configuration to create
+ @return: The new configuration object.
+ """
+ # normalise the path
+ normpath = utils.resourceref.norm(path)
+ cklass = self.get_configuration_class()
+ conf = cklass(normpath, namespace=self.namespace)
+ proxy = ConfigurationProxy(normpath)
+ self.add_configuration(proxy)
+ proxy._set_obj(conf)
+ return conf
+
+ def remove_configuration(self, path):
+ """
+ Remove a Layer object from the Configuration by its reference.
+ """
+ self._remove(utils.resourceref.to_objref(path))
+
+ def list_configurations(self):
+ """
+ List all Layer objects in the Configuration
+ @return: a copy array of layer references.
+ """
+ return [config.get_path() for config in self._objects(type=(Configuration, ConfigurationProxy))]
+
+ def list_all_configurations(self):
+ """
+ List all Layer objects in the Configuration
+ @return: a copy array of layer references.
+ """
+ # TODO
+ # huge performance problem
+ return [config.get_path() for config in self._traverse(type=(Configuration, ConfigurationProxy))]
+
+ def get_configuration(self, path):
+ """
+ Get a Layer object by if path
+ @return: a Layer object
+ """
+ return self._get(utils.resourceref.to_objref(path))
+
+ def get_configuration_by_index(self, index):
+ """
+ Get a Layer object by if indexing number
+ @return: a Layer object
+ """
+ configs = self._objects(type=(Configuration, ConfigurationProxy))
+ return configs[index]
+
+ def get_last_configuration(self):
+ """
+ Get the last Layer object from this configuration hierarchy.
+ @return: a Layer object
+ """
+ last_config = self
+ try:
+ last_config = last_config.get_configuration_by_index(-1)
+ return last_config.get_last_configuration()
+ except IndexError:
+ return self
+
+ def get_configuration_class(self):
+ """
+ return the default configuration class retrieved from the project if it is found.
+ Otherwise return cone.public.api.Configuration.
+ """
+ try:
+ return self.get_project().get_configuration_class()
+ # catch the Parent/Project NotFound exception
+ except exceptions.NotFound:
+ return Configuration
+
+ def add(self, child, policy=container.REPLACE):
+ """
+ A generic add function to add child objects. The function is intended to act as
+ proxy function that call the correct add function based on the child objects class.
+
+ Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+ @param child: the child object to add
+ @raise IncorrectClassError: if the given class cannot be added to this object.
+ """
+ if isinstance(child, Configuration):
+ self.add_configuration(child)
+ elif isinstance(child, ConfigurationProxy):
+ self.add_configuration(child)
+ elif isinstance(child, Base):
+ self._add(child)
+ else:
+ raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+ def layered_content(self, layers=None):
+ """
+ fetch content from first to last and override content
+ if it is found from a later layer
+ Create an array of the layers based on the layer indexes.
+ """
+ configuration_array = []
+ if layers == None:
+ configuration_array = self.list_configurations()
+ else:
+ all = self.list_configurations()
+ for i in layers:
+ configuration_array.append(all[i])
+
+ content = container.DataContainer()
+ for configuration_path in configuration_array:
+ content_folder = self.get_configuration(configuration_path).get_layer().content_folder()
+ content_path = content_folder.get_current_path()
+ for content_file in content_folder.list_resources("", True):
+ source_file = utils.resourceref.join_refs([content_path, content_file])
+ content.add_value(content_file, source_file)
+
+ return content
+
+
+class Configuration(CompositeConfiguration):
+ """
+ A Configuration is a container that can hold several Layer objects.
+ """
+
+ def __init__(self, ref="", **kwargs):
+ self.path = kwargs.get('path') or ref
+ self.namespace = kwargs.get('namespace', '')
+ self.name = utils.resourceref.to_objref(self.path)
+ super(Configuration, self).__init__(utils.resourceref.to_objref(self.path))
+ self.container = True
+
+ def _default_object(self, name):
+ return Feature(name)
+
+ def _supported_type(self, obj):
+ if isinstance(obj, Configuration) \
+ or isinstance(obj, Feature) \
+ or isinstance(obj, Data) \
+ or isinstance(obj, ConfigurationProxy) \
+ or isinstance(obj, View) \
+ or isinstance(obj, Base):
+ return True
+ else:
+ return False
+
+ def _dict(self):
+ """
+ Return the public variables in a dictionary
+ """
+ dict = {}
+ for key in self.__dict__.keys():
+ if key.startswith('_'):
+ continue
+ else:
+ dict[key] = self.__dict__[key]
+ dict['namespace'] = self.namespace
+ return dict
+
+ def get_name(self):
+ """
+ Return the name of the configuration
+ """
+ return self.name
+
+ def set_name(self, name):
+ """
+ Set the name
+ """
+ self.name = name
+
+ def get_path(self):
+ """
+ Return the path of the configuration resource
+ """
+ return self.path
+
+ def set_path(self, path):
+ """
+ Set the path of the configuration resource, and update the name and ref to correspond
+ """
+ self.path = path
+ #self.name = utils.resourceref.to_objref(self.path)
+ self.set_ref(utils.resourceref.to_objref(self.path))
+
+ #@property
+ def get_full_path(self):
+ """
+ Return the path of the configuration resource
+ """
+ try:
+ parentconfig = self._find_parent(type=Configuration)
+ parent_path = utils.resourceref.get_path(parentconfig.get_path())
+ except exceptions.NotFound:
+ parent_path = ""
+
+ return utils.resourceref.join_refs([parent_path, self.path])
+
+ def get_layer(self):
+ """
+ Get the layer object where this Configuration is located.
+ """
+ if not hasattr(self, "layer"):
+ layerpath = utils.resourceref.get_path(self.get_path())
+ # hardcoded removal of confml folder from the layer path it is there
+ layerpath = utils.resourceref.remove_end(layerpath, '/confml')
+ self.layer = Layer(self.get_storage(), layerpath)
+ """ Add the sublayers to this layer if they are different from this configuration """
+ for configpath in self.list_configurations():
+ sublayer_path = utils.resourceref.get_path(self.get_configuration(configpath).get_full_path())
+ sublayer_path = utils.resourceref.remove_end(sublayer_path, '/confml')
+ if sublayer_path != utils.resourceref.get_path(self.get_path()):
+ self.layer.add_layer(self.get_configuration(configpath).get_layer())
+ return self.layer
+
+ def set_namespace(self, namespace):
+ """
+ @param namespace: The new namespace of the object
+ """
+ self._namespace = namespace
+ #self.root.set_namespace(namespace)
+
+ def get_namespace(self):
+ """
+ @return: The reference of the object.
+ """
+ return self._namespace
+
+ def del_namespace(self):
+ """
+ @return: The reference of the object.
+ """
+ self._namespace = None
+ namespace = property(get_namespace, set_namespace, del_namespace)
+
+ def list_resources(self, empty_folders=False):
+ """
+ List all resources used in this configuration
+ """
+ """
+ 1. First ensure that all configuration resource files are added
+ 2. Then add all layer resources
+ 3. Make the list distinct
+ """
+
+
+ resources = [self.get_full_path()]
+ for config in self._traverse(type=Configuration):
+ resources.append(config.get_full_path())
+ layer = self.get_layer()
+ for resref in layer.list_all_resources(empty_folders):
+ resources.append(utils.resourceref.join_refs([layer.get_current_path(), resref]))
+
+ return utils.distinct_array(resources)
+
+ def get_resource(self, ref, mode="r"):
+ """
+ Get the given resource as a Resource object. The resource is searched relative to the
+ Configuration path, e.g. Configuration('test/foo/root.confml') => searches from 'test/foo'.
+ @param ref: the reference path to the requested resource
+ @return: a instance of Resource.
+ """
+ mypath = utils.resourceref.get_path(self.path)
+ myref = utils.resourceref.join_refs([mypath, ref])
+ return self.get_storage().open_resource(myref, mode)
+
+ def get_all_resources(self):
+ """
+ Get all resources in resource list of Resource objects
+ """
+ resources = []
+ res_list = self.list_resources()
+ for res in res_list:
+ resources.append(self.get_storage().open_resource(res))
+ return resources
+
+ def get_root_resource(self):
+ """
+ Get the configuration reference resource.
+ """
+ return self.get_storage().open_resource(self.get_path())
+
+ def get_feature(self, ref):
+ """
+ Get a feature object by its reference.
+ @param ref: The reference to the feature object.
+ @return: A Feature object
+ """
+ return self._get(ref)
+
+ def add_feature(self, feature, namespace=""):
+ """
+ Add a feature object to the configuration.
+ @param feature: The Feature object to add.
+ @param namespace: The sub namespace for the feature.
+ e.g. to add fea2 under fea1 add_feature(fea2, 'fea1')
+ @return: None
+ """
+ self._add_to_path(namespace, feature)
+
+ def remove_feature(self, ref):
+ """
+ remove feature by its reference
+ @param ref:
+ """
+ self._remove(ref)
+
+ def list_features(self):
+ """
+ List immediate features found under the this configuration (the top nodes).
+ The features are also available via the _default_view of the configuration.
+ @return: a list of feature references.
+ """
+ return [fea.get_ref() for fea in self._objects(type=Feature)]
+
+ def list_all_features(self):
+ """
+ List all features found under the this configuration. The features are also
+ available via the _default_view of the configuration.
+ @return: a list of feature references.
+ """
+ return [fea.fqr for fea in self._traverse(type=Feature)]
+
+ def add_data(self, data, policy=container.REPLACE):
+ """
+ Add a data object to this configuration object.
+ @param data: The Data object to add.
+ @return: None
+ """
+ if not self._has(data.attr):
+ self._add(DataContainer(data.attr, container=True))
+ (namespace, name) = utils.dottedref.psplit_ref(data.get_fearef())
+ self._get(data.attr)._add_to_path(namespace, data, policy)
+
+ def get_data(self, ref):
+ """
+ Get a data object by its reference.
+ @param ref: The reference to the data object.
+ @return: A Data object
+ """
+ return self.data._get(ref)
+
+ def remove_data(self, ref):
+ """
+ remove feature by its reference
+ @param ref:
+ """
+ self.data._remove(ref)
+
+ def list_datas(self):
+ """
+ List all datas found under the this configuration.
+ @return: a list of Data references.
+ """
+ if self._has('data'):
+ return [dataelem.fqr for dataelem in self.data._objects(type=Data)]
+ else:
+ return []
+
+ def get_datas(self):
+ """
+ List immediate datas found under the this configuration (the top nodes).
+ @return: a list of Data references.
+ """
+ if self._has('data'):
+ return [dataelem for dataelem in self.data._objects(type=Data)]
+ else:
+ return []
+
+ def list_all_datas(self):
+ """
+ List all Data elements found under the this configuration (or subconfigurations).
+ @return: a list of Data references.
+ """
+ return [dataelem.fqr for dataelem in self._traverse(type=Data)]
+
+ def get_all_datas(self):
+ """
+ List all Data elements found under the this configuration (or subconfigurations).
+ @return: a list of Data references.
+ """
+ return [dataelem for dataelem in self._traverse(type=Data)]
+
+ def list_leaf_datas(self):
+ """
+ List all leaf Data elements (i.e. actually modified settings) found under this configuration (or subconfigurations).
+ @return: A list of Data references.
+ """
+ return [dataelem.fqr for dataelem in self._find_leaves(type=Data)]
+
+ def get_leaf_datas(self):
+ """
+ Get all leaf Data elements (i.e. actually modified settings) found under this configuration (or subconfigurations).
+ @return: A list of Data objects.
+ """
+ return [dataelem for dataelem in self._find_leaves(type=Data)]
+
+ def get_view(self, ref):
+ """
+ Get a view object by its reference.
+ @param ref: The reference to the view object.
+ @return: A View object
+ """
+ # Populate the view object before returning it
+ view = self._get(ref)
+ view.populate()
+ return view
+
+ def add_view(self, viewname):
+ """
+ Add a view object to the configuration.
+ @param viewname: The name of the view to add.
+ @return: None
+ """
+ return self._add(View(viewname))
+
+ def remove_view(self, ref):
+ """
+ Remove a view object from the configuration.
+ @param ref: The reference to the View.
+ @return: None
+ @raise NotFound: when view is not found.
+ """
+ return self._remove(ref)
+
+ def list_views(self):
+ """
+ List all views found under the this configuration.
+ @return: a list of view references.
+ """
+ return [view._path(self) for view in self._traverse(type=View)]
+
+ def save(self):
+ """
+ Save the object to the permanent Storage object. Calls the save operation of
+ all the children.
+ """
+ for child in self._objects():
+ if isinstance(child, (Configuration,ConfigurationProxy)):
+ child.save()
+ self.get_project().unload(self.get_full_path(), self)
+
+ def close(self):
+ """
+ Close the configuration
+ """
+ for child in self._objects():
+ if isinstance(child, (Configuration, ConfigurationProxy)):
+ child.close()
+# if self.get_full_path() != "":
+# self.get_project().unload(self.get_full_path(), self)
+
+ def add(self, child, policy=container.REPLACE):
+ """
+ A generic add function to add child objects. The function is intended to act as
+ proxy function that call the correct add function based on the child objects class.
+
+ Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+ @param child: the child object to add
+ @raise IncorrectClassError: if the given class cannot be added to this object.
+ """
+ if isinstance(child, Feature):
+ self.add_feature(child)
+ elif isinstance(child, View):
+ self._add(child)
+ elif isinstance(child, (Data)):
+ self.add_data(child)
+ else:
+ super(Configuration, self).add(child)
+
+ def get_default_view(self):
+ """
+ Get the default view from this configuration hierarchy.
+ This returns always the view from the Root configuration point of view.
+ """
+ try:
+ parent = self._find_parent_or_default()
+ if parent and isinstance(parent, Configuration):
+ return parent.get_default_view()
+ else:
+ if not hasattr(self, '_default_view'):
+ self._create_default_view()
+ return self._default_view
+ except exceptions.NotFound, e:
+ raise e
+ # raise exceptions.NotFound("Default View is not found! No root configuration?")
+
+ def recreate_default_view(self):
+ try:
+ parent = self._find_parent_or_default()
+ if parent and isinstance(parent, Configuration):
+ parent.recreate_default_view()
+ else:
+ self._create_default_view()
+ except exceptions.NotFound, e:
+ raise e
+ # raise exceptions.NotFound("Default View is not found! No root configuration?")
+
+ def _create_default_view(self):
+ # Rebuild the default view for this Configuration
+ self._default_view = View("_default_view", data=True)
+ self._default_view._parent= self
+ # First add all features of the configuration to the view.
+ # Then add all data elements under the features
+ for child in self._traverse(type=Feature):
+ self._default_view.add_feature(child, child.namespace)
+ for child in self._traverse(type=Data):
+ #parent_config = child._find_parent_or_default(type=Configuration)
+ #print "Adding data %s: fqr: %s from file %s." % (child.get_value(), child.fqr, parent_config.get_path())
+ try:
+ fea = self._default_view.get_feature(child.fqr)
+ fea.add_data(child)
+ except exceptions.NotFound, e:
+ data_parent_config = child._find_parent_or_default(type=Configuration)
+ logging.getLogger('cone').info("Warning: Feature '%s' for data in %s not found." % (child.fqr, data_parent_config.get_path()))
+
+class ConfigurationProxy(container.LoadProxy):
+ """
+ Configuration loading proxy. Loads the configuration from the given reference, when needed.
+ """
+ def __init__(self, path, **kwargs):
+ """
+ The ConfigurationProxy that represents a configuration that is included in another configuration.
+ @param ref: the reference to the storage resource
+ The ConfigurationProxy trust to get the store_interface from the parent object with get_storage() function.
+
+ """
+ container.LoadProxy.__init__(self, path)
+ self.set('_name', utils.resourceref.to_objref(path))
+
+ def _clone(self, **kwargs):
+ """
+ A ConfigurationProxy specific implementation for cloning.
+ Copies all (public) members in dictionary.
+ To clone call the actual object that is proxied as well if the reqursion is on.
+ @param recursion: Boolean to define recursion on or off
+ @param recursion_depth: positive integer to define recursion depth. default is -1 which will
+ perform recursion to all objects.
+ """
+ dict = self._dict()
+ obj = self.__class__(**dict)
+ # handle the recursion argument
+ recursion = kwargs.get('recursion', False)
+ if recursion:
+ recursion_depth = kwargs.get('recursion_depth', -1)
+ if recursion_depth < 0 or recursion_depth > 0:
+ # decrease the recursion
+ kwargs['recursion_depth'] = recursion_depth - 1
+ newobj = self._get_obj()._clone(**kwargs)
+ obj._set_obj(newobj)
+ return obj
+
+ def _dict(self):
+ """
+ Return the public variables in a dictionary
+ """
+ dict = {}
+ for key in self.__dict__.keys():
+ if key.startswith('_'):
+ continue
+ else:
+ dict[key] = self.__dict__[key]
+ return dict
+
+ def _get_mapper(self,modelname):
+ """
+ Return a instance of appropriate mapper for given model.
+ """
+ return mapping.BaseMapper()
+
+class Group(Base):
+ """
+ A Group class. Group is used in View to group up other Group/Feature objects.
+ """
+ def __init__(self, ref="", **kwargs):
+ super(Group, self).__init__(ref, **kwargs)
+ self.name = ref
+ self.support_data = kwargs.get("data", False)
+
+ def _supported_type(self, obj):
+ if isinstance(obj, (Group, \
+ Base, \
+ _FeatureProxy, \
+ FeatureLink)):
+ return True
+ else:
+ return False
+
+ def _default_object(self, name):
+ return Group(name)
+
+ def get_name(self):
+ """
+ Return the name of the configuration
+ """
+ return self.name
+
+ def set_name(self, name):
+ """
+ Set the name
+ """
+ self.name
+
+ def add(self, child, policy=container.REPLACE):
+ """
+ A generic add function to add child objects. The function is intended to act as
+ proxy function that call the correct add function based on the child objects class.
+
+ Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+ @param child: the child object to add
+ @raise IncorrectClassError: if the given class cannot be added to this object.
+ """
+ if isinstance(child, (Group, \
+ Base, \
+ _FeatureProxy, \
+ FeatureLink)):
+ self._add(child)
+ else:
+ raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+ def get_name(self):
+ """
+ Return the name of the configuration
+ """
+ return self.name
+
+ def set_name(self, name):
+ """
+ Set the name
+ """
+ self.name = name
+
+ def add_feature(self, feature, path=""):
+ """
+ Add feature to this Group.
+ """
+ if not isinstance(feature, Feature):
+ raise exceptions.IncorrectClassError("add_feature requires instance of Feature!! Given %s" % feature)
+ if not self.support_data:
+ self._add_to_path(path, _FeatureProxy(feature._name, feature))
+ else:
+ self._add_to_path(path, _FeatureDataProxy(feature._name, feature))
+
+ def remove_feature(self, ref):
+ """
+ remove a given feature from this view by reference.
+ @param ref:
+ """
+ self._remove(ref)
+
+ def get_feature(self, ref):
+ """
+ @param path: The path (ref) to the given feature
+ """
+ try:
+ return self._get(ref)
+ except exceptions.NotFound:
+ raise exceptions.NotFound("Feature '%s' not found." % ref)
+
+ def get_features(self, ref, **kwargs):
+ """
+ Get a list of features that match the ref.
+ Example1: get_features('foo.bar') would be the same as get_feature('foo.bar'), but this returns
+ always a list [].
+ Example2: get_features('foo.*') would try to retrieve a list of all foo children.
+ Example3: get_features('foo.*', type='') would try to retrieve a list of all foo children,
+ that have a defined type.
+ @param path: The path (ref) to the given feature or xpath like expression
+ @return: A list of features.
+ """
+ (startref, last) = utils.dottedref.psplit_ref(ref)
+ startelem = self._get(startref)
+ if last == '**':
+ return [fea for fea in startelem._traverse(**kwargs)]
+ elif last == '*':
+ return [fea for fea in startelem._objects(**kwargs)]
+ else:
+ return [self._get(ref)]
+
+ def list_features(self):
+ """
+ Return a array of all Feature children references under this object.
+ """
+ return [fea.get_ref() for fea in self._objects(type=(_FeatureProxy))]
+
+ def list_all_features(self):
+ """
+ Return a array of all Feature children references under this object.
+ """
+ return [fea.fqr for fea in self._traverse(type=(_FeatureProxy))]
+
+ def add_group(self, groupname):
+ """
+ """
+ self._add(Group(groupname))
+
+ def remove_group(self, ref):
+ """
+ remove a given feature from this view by reference.
+ @param ref:
+ """
+ self._remove(ref)
+
+ def get_group(self, ref):
+ """
+ @param path: The path (ref) to the given feature
+ """
+ return self._get(ref)
+
+ def list_groups(self):
+ """
+ """
+ return [group.get_name() for group in self._objects(type=Group)]
+
+ def populate(self):
+ """
+ Populate or fetch the link to the actual feature for this featureproxy.
+ This method fetches the feature to the _obj member variable and populates also
+ subfeatures.
+ """
+ for child in self._traverse(type=FeatureLink):
+ child.populate()
+
+
+
+class View(Group):
+ """
+ A View class. View is intended to create new or different hierarchies of existing features. A View can contain Group and/or Feature objects.
+ """
+ def __init__(self, ref="", **kwargs):
+ super(View, self).__init__(self.to_ref(ref), **kwargs)
+ self.name = ref
+ self.container = True
+
+ @classmethod
+ def to_ref(cls, ref):
+ """
+ return a view reference converted from name
+ """
+ return ref.replace('.', '').replace('/', '')
+
+
+class Feature(Base):
+ """
+ A Feature class. Feature is the base for all Configurable items in a Configuration.
+ """
+ PROPERTIES = ['value']
+ def __init__(self, ref="", **kwargs):
+ super(Feature, self).__init__(ref, **kwargs)
+ self.name = kwargs.get('name', ref)
+ self.type = kwargs.get('type', None)
+ self._dataproxy = None
+
+ def __copy__(self):
+ dict = {}
+ for key in self.__dict__.keys():
+ if key.startswith('_') or key == 'ref':
+ continue
+ else:
+ dict[key] = self.__dict__[key]
+ fea = self.__class__(self.ref, **dict)
+ return fea
+
+
+ def _supported_type(self, obj):
+ # For now support added for desc element via support for Base
+ if isinstance(obj, (Feature, Option, Base)):
+ return True
+ else:
+ return False
+
+ def add(self, child, policy=container.REPLACE):
+ """
+ A generic add function to add child objects. The function is intended to act as
+ proxy function that call the correct add function based on the child objects class.
+
+ Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+ @param child: the child object to add
+ @raise IncorrectClassError: if the given class cannot be added to this object.
+ """
+ if isinstance(child, Feature):
+ self.add_feature(child)
+ elif isinstance(child, Option):
+ self._add(child, policy)
+ elif isinstance(child, Base):
+ self._add(child, policy)
+ else:
+ raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+ def get_name(self):
+ """
+ Return the name of the configuration
+ """
+ return self.name
+
+ def set_name(self, name):
+ """
+ Set the name
+ """
+ self.name = name
+
+ def get_type(self):
+ return self.type
+
+ def set_type(self, type):
+ self.type = type
+
+ def add_feature(self, feature, path=""):
+ """
+ @param feature: The Feature object to add
+ """
+ configuration = self.find_parent(type=Configuration)
+ if configuration:
+ feapath = utils.dottedref.join_refs([self._path(configuration), path])
+ configuration.add_feature(feature, feapath)
+ else:
+ self._add_to_path(path, feature)
+
+ def get_feature(self, path):
+ """
+ @param path: The path (ref) to the given feature
+ """
+ return self._get(path)
+
+ def remove_feature(self, ref):
+ """
+ remove a given feature from this view by reference.
+ @param ref:
+ """
+ configuration = self.find_parent(type=Configuration)
+ if configuration:
+ fullfqr = utils.dottedref.join_refs([self._path(configuration), ref])
+ configuration.remove_feature(fullfqr)
+ else:
+ self._remove(ref)
+
+ def list_features(self):
+ """
+ Return a array of all Feature children references under this object.
+ """
+ return [fea.get_ref() for fea in self._objects(type=Feature)]
+
+ def list_all_features(self):
+ """
+ Return a array of all Feature children references under this object.
+ """
+ return [fea._path(self) for fea in self._traverse(type=Feature)]
+
+ def add_option(self, option):
+ """
+ @param option: option object
+ """
+ if not isinstance(option, Option):
+ raise TypeError("%r is not an instance of Option!" % option)
+ self._add(option)
+
+ def create_option(self, name, value):
+ """
+ @param name: option name
+ @param value: option value
+ """
+ self._add(Option(name, value))
+
+ def get_option(self, ref):
+ """
+ @param name: The option reference of the option (as returned by list_options())
+ """
+ real_ref = 'opt_' + ref
+ obj = self._get(real_ref)
+ if not isinstance(obj, Option):
+ raise TypeError('Object %r is not an instance of Option (%r instead)' % (real_ref, type(obj)))
+ return obj
+
+ def remove_option(self, ref):
+ """
+ remove a given option from this feature by option reference.
+ """
+ real_ref = 'opt_' + ref
+ obj = self._get(real_ref)
+ if not isinstance(obj, Option):
+ raise TypeError('Trying to remove option with ref %r, but object with ref %r is not an instance of Option (%s instead)' % (ref, real_ref, type(obj)))
+ self._remove(real_ref)
+
+ def list_options(self):
+ """
+ Return a array of all Option children references under this object.
+ """
+ # Return option refs without the leading 'opt_'
+ return [opt.ref[4:] for opt in self._objects(type=Option)]
+
+ def get_value(self, attr=None):
+ """
+ Get the current value of the feature
+ @param attr: The attribute name of the data. E.g. attr='data', attr='rfs'
+ """
+ # Do not allow getting of setting of sequence values directly with Feature object
+ if not self.is_sequence():
+ return self.get_value_cast(self.dataproxy._get_value(attr), attr)
+ else:
+ """ get the feature specific data from sequence => a column of data table """
+ coldata = []
+ feasequence = self.get_sequence_parent()
+ feapath = self._path(feasequence)
+ for row in feasequence.data:
+ feadata = row.get_feature(feapath)
+ coldata.append(feadata.value)
+ return coldata
+
+ def set_value(self, value, attr=None):
+ """
+ Set the current value for this feature. Set the value on the topmost layer.
+ @param value: the value to set
+ """
+ # Do not allow setting of setting of sequence values directly with Feature object
+ if not self.is_sequence():
+ value = self.set_value_cast(value, attr)
+ self.dataproxy._set_value(value, attr)
+
+ def del_value(self, attr=None):
+ """
+ Delete the topmost value for this feature.
+ """
+ if not self.is_sequence():
+ self.dataproxy._del_value(attr)
+
+ def get_value_cast(self, value, attr=None):
+ """
+ A function to perform the value type casting in get operation
+ @param value: the value to cast
+ @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
+ """
+ return value
+
+ def set_value_cast(self, value, attr=None):
+ """
+ A function to perform the value type casting in the set operation
+ @param value: the value to cast
+ @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
+ """
+ return value
+
+ def get_original_value(self, attr=None):
+ """
+ Get the current value of the feature
+ @param attr: The attribute name of the data. E.g. attr='data', attr='rfs'
+ """
+ # Do not allow getting of setting of sequence values directly with Feature object
+ if not self.is_sequence():
+ return self.dataproxy._get_value(attr)
+ else:
+ """ get the feature specific data from sequence => a column of data table """
+ coldata = []
+ feasequence = self.get_sequence_parent()
+ feapath = self._path(feasequence.data)
+ for row in feasequence.data:
+ feadata = row.get_feature(feapath)
+ coldata.append(feadata.value)
+ return coldata
+
+ def add_data(self, data):
+ """
+ Add a data value.
+ @param data: A Data object
+ """
+ try:
+ return self.dataproxy._add_data(data)
+ except AttributeError:
+ self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+ return self.dataproxy._add_data(data)
+
+ def get_data(self, attr=None):
+ """
+ Helper function to get the topmost data value from the default view.
+ @param attr: The attribute name of the data. E.g. attr='data', attr='rfs'
+ """
+ try:
+ return self.dataproxy._get_data(attr)
+ except AttributeError:
+ self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+ return self.dataproxy._get_data(attr)
+
+ def get_datas(self):
+ """
+ Helper function to get the data values from the default view.
+ """
+ try:
+ return self.dataproxy._get_datas()
+ except AttributeError:
+ self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+ return self.dataproxy._get_datas()
+
+ def get_valueset(self):
+ """
+ Get the ValueSet object for this feature, that has the list of available values.
+ """
+ if self.get_type() == 'boolean':
+ return ValueSet([True, False])
+ elif self.get_type() == 'int':
+ return ValueRange(0, sys.maxint)
+ elif self.get_type() == 'string':
+ return ValueRe('.*')
+ elif self.get_type() in ('selection', 'multiSelection'):
+ values = []
+ for opt in self._objects(type=Option):
+ v = opt.get_value()
+ if v is not None: values.append(v)
+ return ValueSet(values)
+
+ def is_sequence(self):
+ """ Return true if the feature is a sequence or part of a sequence """
+ try:
+ return self._parent.is_sequence()
+ except AttributeError:
+ return False
+
+ def get_sequence_parent(self):
+ """ Try to get a FeatureSequence object for this Feature if it is found """
+ try:
+ return self._parent.get_sequence_parent()
+ except AttributeError:
+ return None
+
+ def getdataproxy(self):
+ if self._dataproxy == None:
+ self.dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+ return self._dataproxy
+ def setdataproxy(self, value): self._dataproxy = value
+ def deldataproxy(self): self._dataproxy = None
+ dataproxy = property(getdataproxy, setdataproxy, deldataproxy)
+ value = property(get_value, set_value, del_value)
+
+class FeatureSequence(Feature):
+ POLICY_REPLACE = 0
+ POLICY_APPEND = 1
+ POLICY_PREPEND = 2
+ """
+ A Feature class. Feature is the base for all Configurable items in a Configuration.
+ """
+ dataelem_name = '?datarows'
+ template_name = '?template'
+ def __init__(self, ref="", **kwargs):
+ super(FeatureSequence, self).__init__(ref)
+ self.name = kwargs.get('name', ref)
+ self.type = 'sequence'
+ self.mapKey = kwargs.get('mapKey')
+ self.mapValue = kwargs.get('mapValue')
+ self._templatedata = None
+
+ def _get_policy(self, data):
+ """
+ parse the policy from a policy string and return a constant
+ @return: POLICY_* constant
+ """
+ try:
+ containerdata = utils.get_list(data._get_parent()._get(data.get_ref()))
+ firstdata = containerdata[0]
+ except AttributeError:
+ firstdata = data
+
+ if firstdata.policy == 'append':
+ return self.POLICY_APPEND
+ elif firstdata.policy == 'prefix':
+ return self.POLICY_PREPEND
+ elif firstdata == data:
+ # otherwise the policy is either replace or undefined
+ # (firstdata.policy == 'replace' or firstdata.policy == ''):
+ return self.POLICY_REPLACE
+ else:
+ return self.POLICY_APPEND
+
+ def _set_template_data(self, data=None):
+ """
+ Set the template of the feature sequence
+ """
+ # If template data is not existing, create it
+ if data != None:
+ self._templatedata = data
+ for feaname in self.list_features():
+ if self._templatedata._has(feaname):
+ self.get_feature(feaname)._templatedata = self._templatedata._get(feaname)
+ else:
+ subdata = Data(ref=feaname)
+ self.get_feature(feaname)._templatedata = subdata
+ self._templatedata._add(subdata)
+
+ def _add_datarow(self, dataobj=None, policy=POLICY_APPEND):
+ """
+ Add a feature data row for a new data in this sequence
+ """
+ if dataobj == None:
+ dataobj = Data(fqr=self.fqr)
+ elif dataobj.attr != 'data':
+ # Add data rows only for data objects (not e.g. RFS)
+ return
+ fea = FeatureSequenceSub(self.dataelem_name)
+ rowproxy = _FeatureDataProxy(fea._name, fea)
+ """ the imaginary features share the parent relation of the proxy objects """
+ self.dataproxy._add(rowproxy, policy)
+ fea._parent = rowproxy._parent
+ rowproxy._add_data(dataobj)
+ """ update the FeatureSequenceSub index from the index number of dataproxy """
+ fea._index = utils.get_list(self.dataproxy._get(self.dataelem_name)).index(rowproxy)
+ # Create a the subfeatures / columns for the parent feature and
+ # add a data element under each feature.
+ for feaname in self.list_all_features():
+ (pathto_fea, fearef) = utils.dottedref.psplit_ref(feaname)
+ rowproxy.add_feature(FeatureSequenceSub(fearef), pathto_fea)
+ subproxy = rowproxy.get_feature(feaname)
+ subproxy._obj._parent = subproxy._parent
+ if not dataobj._has(feaname):
+ dataobj._add_to_path(pathto_fea, Data(ref=fearef))
+ subproxy._add_data(dataobj._get(feaname))
+
+ def add(self, child, policy=container.REPLACE):
+ """
+ A generic add function to add child objects. The function is intended to act as
+ proxy function that call the correct add function based on the child objects class.
+
+ Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+ @param child: the child object to add
+ @raise IncorrectClassError: if the given class cannot be added to this object.
+ """
+ if isinstance(child, Feature):
+ self.add_feature(child)
+ elif isinstance(child, Option):
+ self._add(child)
+ elif isinstance(child, Base):
+ self._add(child)
+ else:
+ raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+ def add_sequence(self, data=None, policy=POLICY_APPEND):
+ """
+ Add a feature data row for a new data in this sequence
+ """
+ self._add_datarow(None, policy)
+ # set the initial data if it is given
+ rowproxy = utils.get_list(self.dataproxy._get(self.dataelem_name))[-1]
+ if data != None:
+ for index in range(len(data)):
+ rowproxy[index].set_value(data[index])
+ # add the new data sequence/row to the last configuration layer
+ dataobj = rowproxy._get_data()
+ last_config = self.get_root_configuration().get_last_configuration()
+ last_config.add_data(dataobj, container.APPEND)
+ return dataobj
+
+ def set_template(self, data=None):
+ """
+ Set the template of the feature sequence
+ """
+ # If template data is not existing, create it
+ if self._templatedata == None:
+ self._set_template_data(Data(ref=self.ref, template=True))
+ # Add the template data to parent config
+ pconfig = self.find_parent(type=Configuration)
+ pconfig.add_data(self._templatedata)
+
+ if data != None:
+ templdatas = self._templatedata._objects()
+ for index in range(len(data)):
+ templdatas[index].set_value(data[index])
+
+ def get_template(self):
+ """
+ Add a feature data row for a new data in this sequence
+ """
+ #self._set_template(None)
+ # set the initial data if it is given
+ if self._templatedata:
+ return [data.get_value() for data in self._templatedata._objects()]
+ else:
+ return None
+
+ def get_data(self):
+ """
+ Helper function to get the topmost data value from the default view.
+ """
+ if self.dataproxy._has(self.dataelem_name):
+ return utils.get_list(self.dataproxy._get(self.dataelem_name))
+ else:
+ return []
+
+ def add_data(self, data):
+ """
+ Add a data value.
+ @param data: A Data object
+ """
+ # Skip template data adding
+ if data.template:
+ self._set_template_data(data)
+ else:
+ # Get the data index
+ self._add_datarow(data, self._get_policy(data))
+ return
+
+ def get_map_key(self):
+ """
+ Returns the setting that corresponds to mapKey attribute of this sequence feature.
+ """
+ if self.mapKey != None:
+ mapkey = self.get_feature(self.mapKey)
+ return mapkey
+ else:
+ return None
+
+ def get_map_key_value(self,key):
+ """
+ Returns the setting that corresponds to mapKey attribute of this sequence feature.
+ """
+ value = None
+ if self.mapKey != None and self.mapValue != None:
+ data = self.get_data()
+ for item in data:
+ kv = item.get_feature(self.mapKey).get_value()
+ if kv == key:
+ value = item.get_feature(self.mapValue).get_value()
+ return value
+
+ def get_map_value(self):
+ """
+ Returns the setting that corresponds to mapValue attribute of this sequence feature.
+ """
+ if self.mapValue != None:
+ mapvalue = self.get_feature(self.mapValue)
+ return mapvalue
+ else:
+ return None
+
+ def get_value(self, attr=None):
+ """
+ Helper function to get the topmost data value from the default view.
+ """
+ datatable = self.get_data()
+ rettable = []
+ for row in datatable:
+ rowvalues = row.value
+ rettable.append(rowvalues)
+ return rettable
+
+ def set_value(self, value, attr=None):
+ """
+ Set the current value for this feature. Set the value on the topmost layer.
+ @param value: the value to set. The value must be a two dimensional array (e.g. matrix)
+ """
+ # sets the first data element to replace policy
+ try:
+ self.add_sequence(value.pop(0), self.POLICY_REPLACE)
+ # ignore the index error of an empty list
+ except IndexError:
+ pass
+ for row in value:
+ self.add_sequence(row)
+
+ def is_sequence(self):
+ """ Return always true from a sequence object """
+ return True
+
+ def get_sequence_parent(self):
+ """ Return this object as a sequence parent """
+ return self
+
+ value = property(get_value, set_value)
+ data = property(get_data)
+
+class FeatureSequenceCell(Feature):
+ """
+ A Feature class. Feature is the base for all Configurable items in a Configuration.
+ """
+ def __init__(self, ref="", **kwargs):
+ super(Feature, self).__init__(ref)
+ self.name = kwargs.get('name', ref)
+ self.type = 'seqcell'
+
+ def get_value(self, attr=None):
+ """
+ Get the current value of the feature
+ @param attr: The attribute name of the data. E.g. attr='data', attr='rfs'
+ """
+ return self.dataproxy._get_value(attr)
+
+ def set_value(self, value):
+ """
+ Set the current value for this feature. Set the value on the topmost layer.
+ @param value: the value to set
+ """
+ # The sequence cell only updates the latest value in the proxy
+ self.dataproxy.get_data().set_value(value)
+
+ value = property(get_value, set_value)
+
+class FeatureSequenceSub(Feature):
+ """
+ A Feature class. Feature is the base for all Configurable items in a Configuration.
+ """
+ def __init__(self, ref="", **kwargs):
+ super(Feature, self).__init__(ref)
+ self.name = kwargs.get('name', ref)
+ self.type = 'subseq'
+ self._index = 0
+
+ def get_index(self):
+ """
+ @return : the index of the data element for sequential data defined inside the same configuration.
+ 0 for normal data.
+ """
+ return self._index
+
+ def set_value(self, value, attr=None):
+ """
+ Set the current value for this sequence row.
+ @param value: the value row to set
+ """
+ if utils.is_list(value):
+ for subindex in range(0, len(value)):
+ self.dataproxy[subindex].get_data().set_value(value[subindex])
+ else:
+ self.dataproxy.get_data().set_value(value)
+
+ def get_value(self, attr=None):
+ """
+ Set the current value for this feature. Set the value on the topmost layer.
+ @param value: the value to set
+ """
+ # dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+ # The sequence cell only updates the latest value in the proxy
+ childdatas = self.dataproxy._objects()
+ if len(childdatas) > 0:
+ return [subdata.value for subdata in childdatas]
+ else:
+ return self.dataproxy._get_value(attr=attr)
+
+ value = property(get_value, set_value)
+
+
+class FeatureLink(Base):
+ """
+ A _FeatureProxy class. _FeatureProxy is the object that is added to View as a
+ link to the actual Feature object.
+ """
+ def __init__(self, link="", **kwargs):
+ # Store the fully qualified reference to this object
+ self.link = link
+ ref = link.replace('.', '_')
+ super(FeatureLink, self).__init__(ref)
+ self._obj = None
+ self._populated = False
+
+ @property
+ def fqr(self):
+ return self.link
+
+ def populate(self):
+ """
+ Populate or fetch the link to the actual feature for this featureproxy.
+ This method fetches the feature to the _obj member variable and populates also
+ subfeatures.
+ """
+ try:
+ if not self._populated:
+ feas = self.get_default_view().get_features(self.link)
+ # add the found features to the parent
+ for fea in feas:
+ self._get_parent().add_feature(fea._obj)
+ except exceptions.NotFound, e:
+ parent_view = self._find_parent_or_default(type=View)
+ view_name = parent_view.get_name()
+ logging.getLogger('cone').info("Warning: Feature '%s' in view '%s' not found." % (self.link, view_name))
+
+
+class _FeatureProxy(container.ObjectProxyContainer, Base):
+ """
+ A _FeatureProxy class. _FeatureProxy is the object that is added to View as a
+ link to the actual Feature object.
+ """
+ def __init__(self, ref="", obj=None, **kwargs):
+ super(_FeatureProxy, self).__init__(obj, ref)
+ Base.__init__(self, ref)
+ self.support_data = False
+
+ def __getattr__(self, name):
+ """
+ First check if the requested attr is a children then
+ direct all not found attribute calls to the sub object getattr
+ """
+ try:
+ return self.__dict__['_children'][name]
+ except KeyError:
+ return getattr(self._obj, name)
+
+ def __getitem__(self, index):
+ return self._objects()[index]
+
+ def __setitem__(self, index, value):
+ raise exceptions.NotSupported()
+
+ def __delitem__(self, index):
+ item = self.__getitem__(index)
+ return self._remove(item.get_ref())
+
+ def __len__(self):
+ return len(self._order)
+
+ def _supported_type(self, obj):
+ if isinstance(obj, _FeatureProxy):
+ return True
+ else:
+ return False
+
+ def _default_object(self, name):
+ return Group(name)
+
+ def _set_parent(self, newparent):
+ """
+ @param newparent: The new parent object
+ @return: None
+ """
+ self._parent = newparent
+
+ def add_feature(self, feature, path=""):
+ """
+ """
+ if not isinstance(feature, Feature):
+ raise exceptions.IncorrectClassError("add_feature requires instance of Feature!! Given %s" % feature)
+ if not self.support_data:
+ self._add_to_path(path, _FeatureProxy(feature._name, feature))
+ else:
+ self._add_to_path(path, _FeatureDataProxy(feature._name, feature))
+
+ def remove_feature(self, ref):
+ """
+ remove a given feature from this view by reference.
+ @param ref:
+ """
+ self._remove(ref)
+
+ def get_feature(self, path):
+ """
+ @param path: The path (ref) to the given feature
+ """
+ return self._get(path)
+
+ def list_features(self):
+ """
+ Return a array of all Feature children references under this object.
+ """
+ return self._list()
+
+ def list_all_features(self):
+ """
+ Return a array of all Feature children references under this object.
+ """
+ return [fea._path(self) for fea in self._traverse(type=_FeatureProxy)]
+
+ def populate(self):
+ """
+ Dummy implementation of populate
+ """
+ pass
+
+
+class _FeatureDataProxy(_FeatureProxy):
+ """
+ A Feature class. Feature is the base for all Configurable items in a Configuration.
+ """
+ DEFAULT_KEY = 'data'
+ def __init__(self, ref="", obj=None, **kwargs):
+ # Initialize _obj to None, because __getattr__(), __setattr__()
+ # and __delattr__() access it.
+ # Note that we cannot use self._obj = None here, since that would
+ # invoke __setattr__(), causing a kind of a chicken-and-egg problem
+ object.__setattr__(self, '_obj', None)
+
+ super(_FeatureDataProxy, self).__init__(ref, obj)
+ self.support_data = True
+ """ Create the data container of all types of data. Add the key for the default key. """
+
+ self.defaultkey = _FeatureDataProxy.DEFAULT_KEY
+ self.datas = {self.defaultkey : []}
+
+ def __getattr__(self, name):
+ """
+ """
+ if object.__getattribute__(self, '_obj') is not None:
+ self._obj.dataproxy = self
+
+ if name in Feature.PROPERTIES:
+ return getattr(self._obj, name)
+ else:
+ return super(_FeatureDataProxy, self).__getattr__(name)
+
+ def __setattr__(self, name, value):
+ """
+ """
+ if object.__getattribute__(self, '_obj') is not None:
+ self._obj.dataproxy = self
+
+ if name in Feature.PROPERTIES:
+ return setattr(self._obj, name, value)
+ else:
+ super(_FeatureDataProxy, self).__setattr__(name, value)
+
+ def __delattr__(self, name):
+ """
+ """
+ if name in Feature.PROPERTIES:
+ return delattr(self._obj, name)
+ else:
+ return super(_FeatureDataProxy, self).__delattr__(name)
+
+ def _add_data(self, data):
+ """
+ Add a data value.
+ @param data: A Data object
+ """
+ try:
+ self.datas[data.attr].append(data)
+ except KeyError:
+ """ Create a list object for missing attribute """
+ self.datas[data.attr] = []
+ self.datas[data.attr].append(data)
+
+ def _get_data(self, attr=None):
+ """
+ Get the data value. in sequence setting cases returns an array of data.
+ """
+ dataattr = attr or self.defaultkey
+ try:
+ if len(self.datas[dataattr]) > 0:
+ return self.datas[dataattr][-1]
+ else:
+ return None
+ except KeyError:
+ """ return None for missing attribute """
+ return None
+
+ def _get_datas(self, attr=None):
+ """
+ Get the entire data array.
+ """
+ dataattr = attr or self.defaultkey
+ return self.datas[dataattr]
+
+ def _get_value(self, attr=None):
+ """
+ Get the topmost data value.
+ """
+ if self._get_data(attr):
+ return self._get_data(attr).get_value()
+ else:
+ return None
+
+ def _set_value(self, datavalue, attr=None):
+ """
+ Set the value for the feature the last configuration in the current hierarchy
+ @param value: The value for the feature.
+ @return: The created Data object.
+ """
+ # Make sure that data value exists only once the the last configuration layer
+ # So if last_data exists on last layer, update the value of that data element.
+ # otherwise create a new data elem to the topmost layer
+ dataobj = self._get_data(attr)
+ last_config = self.get_root_configuration().get_last_configuration()
+ if dataobj and dataobj.find_parent(type=Configuration) == last_config:
+ dataobj.set_value(datavalue)
+ else:
+ dataobj = Data(fqr=self.fqr, value=datavalue, attr=attr)
+ last_config.add_data(dataobj)
+ self._add_data(dataobj)
+ return dataobj
+
+ def _del_value(self, attr=None):
+ """
+ Remove the
+ """
+ data = self._get_data(attr)
+ if data:
+ dataattr = attr or self.defaultkey
+ parentconfig = data.find_parent(type=Configuration)
+ if parentconfig:
+ parentconfig.remove_data(data.get_fullfqr())
+ del self.datas[dataattr][-1]
+
+ def _get_values(self, attr=None):
+ """
+ Get the topmost data value.
+ """
+ dataattr = attr or self.defaultkey
+ return [dataelem.get_value() for dataelem in self.datas[dataattr]]
+
+
+class DataBase(Base):
+ def __init__(self, ref="", **kwargs):
+ super(DataBase, self).__init__(ref, **kwargs)
+
+ def _supported_type(self, obj):
+ if isinstance(obj, (DataContainer, DataBase)):
+ return True
+ else:
+ return False
+
+ def _default_object(self, name):
+ return Data(ref=name)
+
+ def count(self):
+ return len(self._objects())
+
+ def add(self, child, policy=container.REPLACE):
+ """
+ A generic add function to add child objects. The function is intended to act as
+ proxy function that call the correct add function based on the child objects class.
+
+ Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+ @param child: the child object to add
+ @raise IncorrectClassError: if the given class cannot be added to this object.
+ """
+ if isinstance(child, (Data)):
+ self._add(child, container.APPEND)
+ else:
+ raise exceptions.IncorrectClassError("Cannot add %s object to %s" % (child, self))
+
+
+class DataContainer(DataBase):
+ def __init__(self, ref="", **kwargs):
+ super(DataContainer, self).__init__(ref, **kwargs)
+
+
+class Data(DataBase):
+ """
+ The data element can contain any data setting for a feature. The data element can be
+ a value definition for any type of data. It basically just links some data to a feature.
+ The default Data attribute is 'data', but it can be any string. For example current use case
+ is 'rfs'.
+ """
+ def __init__(self, **kwargs):
+ """
+ @param ref: the reference to the feature. E.g. foo
+ @param fqr: the full reference to the feature. E.g. 'foo.bar'
+ @param value: the value of the data
+ @param attr: the attribute which the Data object defines. e.g. default is 'data'. But could be
+ for example 'rfs'
+ """
+ name = kwargs.get('ref', '')
+ self.fearef = kwargs.get('fqr', None)
+ if self.fearef:
+ (namespace, name) = utils.dottedref.psplit_ref(self.fearef)
+ super(Data, self).__init__(name)
+ self.value = kwargs.get('value', None)
+ self.attr = kwargs.get('attr') or 'data'
+ self.policy = kwargs.get('policy', '')
+ self.template = kwargs.get('template', False)
+ self.map = kwargs.get('map')
+
+ def get_fearef(self):
+ if self.fearef:
+ return self.fearef
+ else:
+ return self.fqr
+
+ def get_value(self):
+ if self.map != None:
+ ref = utils.resourceref.to_dref(self.get_map_ref())
+ key = self.get_map_key_value()
+ dview = self.get_root_configuration().get_default_view()
+ fea = dview.get_feature(ref)
+ return fea.get_map_key_value(key)
+ else:
+ return self.value
+
+ def get_map(self):
+ return self.map
+
+ def set_map(self, map):
+ self.map = map
+ if self.value:
+ #Either value or mapping can be defined. Not both.
+ self.value = None
+
+ def get_map_ref(self):
+ if self.map != None:
+ return utils.DataMapRef.get_feature_ref(self.map)
+ else:
+ return None
+
+ def get_map_key_value(self):
+ if self.map != None:
+ return utils.DataMapRef.get_key_value(self.map)
+ else:
+ return None
+
+ def set_value(self, value):
+ self.value = value
+ if self.map:
+ #Either value or mapping can be defined. Not both.
+ self.map = None
+
+ def get_policy(self): return self._policy
+ def set_policy(self, value): self._policy = value
+ def del_policy(self): self._policy = None
+ policy = property(get_policy, set_policy, del_policy)
+
+
+class ValueSet(sets.Set):
+ """
+ A value set object to indicate a set of possible values for a feature.
+ e.g. A boolean feature ValueSet([True, False])
+ """
+ def __init__(self, initial_set=None):
+ super(ValueSet, self).__init__(initial_set or [])
+
+
+class ValueRange(object):
+ """
+ """
+ def __init__(self, fromvalue, tovalue, step=1):
+ self.fromvalue = fromvalue
+ self.tovalue = tovalue
+ self.step = step
+
+ def __contains__(self, value):
+ return self.fromvalue <= value and value <= self.tovalue and (value-self.fromvalue) % self.step == 0
+
+
+class ValueRe(object):
+ """
+ """
+ def __init__(self, regexp):
+ self.regexp = re.compile(regexp)
+
+ def __contains__(self, value):
+ if isinstance(value, str):
+ return self.regexp.match(value)
+ else:
+ return False
+
+
+class Option(Base):
+ """
+ Confml option class.
+ """
+ def __init__(self, name, value, **kwargs):
+ super(Option, self).__init__(Option.to_optref(value, kwargs.get('map', None)))
+ self.name = name
+ self.value = value
+ self.map = kwargs.get('map', None)
+ self.relevant = kwargs.get('relevant', None)
+
+ @classmethod
+ def to_optref(cls, value, map):
+ """
+ @return: An option reference converted from value or map, depending
+ on which one is not None.
+ """
+ if value is not None:
+ return "opt_value_%s" % value.replace('.', '').replace('/', '').replace(' ', '')
+ elif map is not None:
+ return "opt_map_%s" % map.replace('.', '').replace('/', '').replace(' ', '')
+ else:
+ raise ValueError("Both value and map are None!")
+
+ def get_name(self):
+ return self.name
+
+ def get_value(self):
+ return self.value
+
+ def __cmp__(self, other):
+ try:
+ ref = getattr(other, 'ref')
+ except AttributeError:
+ ref = other
+ if self.ref < ref:
+ return -1
+ elif self.ref == ref:
+ return 0
+ else:
+ return 1
+
+
+class Storage(object):
+ """
+ A general base class for all storage type classes
+ """
+ """ File open modes """
+ MODE_UNKNOWN= -1
+ MODE_READ = 1
+ MODE_WRITE = 2
+ MODE_APPEND = 3
+ MODE_DELETE = 4
+
+ def __init__(self, path):
+ """
+ @param path: the reference to the root of the storage.
+ """
+ self.rootpath = path
+ self.curpath = ""
+ self.container = True
+ self.__opened_res__ = {}
+
+ def __opened__(self, res):
+ """
+ Internal function to add a newly opened Resource object to the list of open resources.
+ @param res: The resource object
+ """
+ if self.__opened_res__.has_key(res.path):
+ self.__opened_res__[res.path].append(res)
+ else:
+ self.__opened_res__[res.path] = [res]
+
+ def __closed__(self, res):
+ """
+ Internal function to remove a Resource object from the list of open resources.
+ @param res: The resource object to remove
+ @raise StorageException if the given resource object is not found:
+ """
+ try:
+ self.__opened_res__[res.path].remove(res)
+ if len(self.__opened_res__[res.path]) == 0:
+ del self.__opened_res__[res.path]
+ except KeyError, e:
+ raise exceptions.StorageException("No such %s open resource! %s" % (res, e))
+
+ def __has_open__(self, ref):
+ """
+ Internal function to find out if any Resource objects are open from given ref.
+ @param ref: The resource ref
+ @return: True if resources found. Otherwise False.
+ """
+ return self.__opened_res__.has_key(ref)
+
+ def __get_open__(self, path):
+ """
+ Internal function to get all resource opened on a certain ref .
+ @param ref: The resource ref
+ @return: A list of open resources. Empty list if nothing is found
+ """
+ if self.__has_open__(path):
+ # return a copy of currently open resources
+ return self.__opened_res__[path][:]
+ else:
+ return []
+
+ def __has_resource__(self, res):
+ """
+ Internal function to find out if the given Resource objects is open in this storage.
+ @param ref: The resource object
+ @return: True if resources found. Otherwise False.
+ """
+ try:
+ res = self.__opened_res__[res.path].index(res)
+ return True
+ except KeyError, e:
+ return False
+
+ @classmethod
+ def open(cls,path, mode="r", **kwargs):
+ """
+ Class method for opening an instance of Storage
+ @param path: path to storage, which will determine what type of storage is initiated.
+ """
+ # import all storage instances
+ from cone.storage import storages
+ for storagename in storages:
+ storagemodule = 'cone.storage.'+storagename
+ module = __import__(storagemodule)
+ for storage_class in utils.all_subclasses(Storage):
+ if storage_class.supported_storage(path):
+ if hasattr(storage_class, '__open__'):
+ return storage_class.__open__(path, mode, **kwargs)
+ else:
+ return storage_class(path, mode, **kwargs)
+
+ obj = Storage(path)
+ return obj
+
+ @classmethod
+ def supported_storage(cls, path):
+ """
+ Class method for determing if the given clas supports a storage by given path.
+ E.g. foo.zip, foo.cpd, foo/bar, http://foo.com/
+ @param path:
+ @return: Boolean value. True if the storage of the path is supported. False if not.
+ """
+ return False
+
+ def set_path(self, path):
+ """
+ """
+ self.rootpath = path
+
+ def get_path(self):
+ """
+ """
+ return self.rootpath
+
+ def set_current_path(self, path):
+ """
+ @param path: the current path under the Storage.
+ """
+ self.curpath = utils.resourceref.remove_end_slash(utils.resourceref.remove_begin_slash(path))
+
+ def get_current_path(self):
+ """
+ get the current path under the Storage.
+ """
+ return self.curpath
+
+ def close(self):
+ """
+ Close the repository, which will save and close all open resources.
+ """
+ for openref in self.__opened_res__.keys():
+ for res in self.__get_open__(openref):
+ self.close_resource(res)
+
+ def save(self):
+ """
+ Flush changes from all resources to the repository.
+ """
+ for openref in self.__opened_res__.keys():
+ for res in self.__get_open__(openref):
+ self.save_resource(res)
+
+ def open_resource(self, path, mode="r"):
+ """
+ Open the given resource and return a File object.
+ @param path : reference to the resource
+ @param mode : the mode in which to open. Can be one of r = read, w = write, a = append.
+ raises a NotResource exception if the ref item is not a resource.
+ """
+ raise exceptions.NotSupportedException()
+
+ def delete_resource(self, path):
+ """
+ Delete the given resource from storage
+ @param path: reference to the resource
+ raises a NotSupportedException exception if delete operation is not supported by the storage
+ """
+ raise exceptions.NotSupportedException()
+
+ def close_resource(self, path):
+ """
+ Close a given resource instance. Normally this is called by the Resource object
+ in its own close.
+ @param path the reference to the resource to close.
+ """
+ raise exceptions.NotSupportedException()
+
+ def is_resource(self, path):
+ """
+ Return true if the ref is a resource
+ @param ref : reference to path where resources are searched
+ """
+ raise exceptions.NotSupportedException()
+
+ def list_resources(self, path, recurse=False):
+ """
+ find the resources under certain ref/path
+ @param ref : reference to path where resources are searched
+ @param recurse : defines whether to return resources directly under the path or does the listing recurse to subfolders.
+ Default value is False. Set to True to enable recursion.
+ """
+ return []
+
+ def import_resources(self, paths, storage):
+ """
+ import resources from a list of resources to this storage
+ @param paths : a list of Resourse objects.
+ @param storage : the external storage from which files are imported.
+ """
+ raise exceptions.NotSupportedException()
+
+ def export_resources(self, paths, storage):
+ """
+ export resources from this storage based on a list of reference to this storage
+ @param path : a list of resource paths in this storage (references).
+ @param storage : the external storage where to export.
+ """
+ raise exceptions.NotSupportedException()
+
+ def close_resource(self, path):
+ """
+ Close a given resource instance. Normally this is called by the Resource object
+ in its own close.
+ @param ref the reference to the resource to close.
+ """
+ raise exceptions.NotSupportedException()
+
+ def save_resource(self, path):
+ """
+ Flush the changes of a given resource instance. Normally this is called by the Resource object
+ in its own save.
+ @param ref the reference to the resource to close.
+ """
+ raise exceptions.NotSupportedException()
+
+ def create_folder(self, path):
+ """
+ Create a folder entry to a path
+ @param path : path to the folder
+ """
+ raise exceptions.NotSupportedException()
+
+ def delete_folder(self, path):
+ """
+ Delete a folder entry from a path. The path must be empty.
+ @param path : path to the folder
+ """
+ raise exceptions.NotSupportedException()
+
+ def is_folder(self, path):
+ """
+ Check if the given path is an existing folder in the storage
+ @param path : path to the folder
+ """
+ raise exceptions.NotSupportedException()
+
+ def get_mode(self, mode_str):
+ if mode_str.find("w") != -1:
+ return self.MODE_WRITE
+ elif mode_str.find("r") != -1:
+ return self.MODE_READ
+ elif mode_str.find("a") != -1:
+ return self.MODE_APPEND
+ elif mode_str.find("d") != -1:
+ return self.MODE_DELETE
+ else:
+ return self.MODE_UNKNOWN
+
+ def unload(self, path, object):
+ """
+ Dump a given object to the storage
+ @param object: The object to dump to the storage, which is expected to be an instance
+ of Base class.
+ @param path: The reference where to store the object
+ @param object: The object instance to dump
+ @raise StorageException: if the given object cannot be dumped to this storage
+ """
+ raise exceptions.NotSupportedException()
+
+ def load(self, path):
+ """
+ Load an object from a reference.
+ @param path: The reference where to load the object
+ @raise StorageException: if the given object cannot be loaded as an object from this storage
+ """
+ raise exceptions.NotSupportedException()
+
+ path = property(get_path, set_path)
+
+class Resource(object):
+ STATE_OPEN = 0
+ STATE_CLOSE = 1
+ def __init__(self, storage, path, mode=Storage.MODE_READ):
+ self.storage = storage
+ self.path = path
+ self.mode = mode
+ self.state = Resource.STATE_OPEN
+ self.content_info = None
+
+ def get_path(self):
+ return self.path
+
+ def close(self):
+ """
+ Close the resource.
+ Note1: the resource object cannot be accessed anymore after it has been closed.
+ Note2: the changes are not automatically saved. The save operation must be explicitly called,
+ to save data.
+ """
+ self.storage.close_resource(self.path)
+ self.state = Resource.STATE_OPEN
+
+ def read(self, bytes=0):
+ """
+ Read data.
+ """
+ raise exceptions.NotSupportedException()
+
+ def write(self, string):
+ """
+ Write data.
+ """
+ raise exceptions.NotSupportedException()
+
+ def truncate(self, size=0):
+ """
+ Trunkate this resource data to the given size.
+ @param size: The size to trunkate. Default value is zero, which make the resource empty.
+ """
+ raise NotSupportedException()
+
+ def save(self, size=0):
+ """
+ Save all changes to data to storage.
+ """
+ raise NotSupportedException()
+
+ def get_mode(self):
+ return self.storage.get_mode(self.mode)
+
+ def get_size(self):
+ """
+ Return the size of this resource in bytes.
+
+ Note that this does not work in write mode.
+ @return: The resource size in bytes:
+ @raise exceptions.StorageException: The resource was opened in write mode.
+ """
+ raise exceptions.NotSupportedException()
+
+ def get_content_info(self):
+ """
+ Return the ContentInfo class that contains content information about
+ resource.
+ """
+ raise exceptions.NotSupportedException()
+
+class ContentInfo(object):
+ """
+ A ContentInfo object is used to describe content of Resource.
+ """
+ logger = logging.getLogger('cone.contentinfo')
+
+
+ def __init__(self, mimetype, mimesubtype):
+ #: MIME Media type (http://www.iana.org/assignments/media-types/)
+ #: as a string. E.g. 'image' or 'application'
+ self.mimetype = mimetype
+ #: MIME Media subtype as a string. E.g. 'svg+xml' or 'bmp'.
+ self.mimesubtype = mimesubtype
+
+ @property
+ def content_type(self):
+ """
+ Returns MIME Media type (http://www.iana.org/assignments/media-types/)
+ and subtype as a string. E.g. 'image/bmp'.
+ """
+ return self.mimetype + '/' + self.mimesubtype
+
+class ImageContentInfo(ContentInfo):
+
+ """
+ A ImageContentInfo object is used to describe content of image Resources.
+ """
+ def __init__(self):
+ ContentInfo.__init__(self, 'image', '')
+
+class BmpImageContentInfo(ImageContentInfo):
+ """
+ A BmpImageContentInfo object is used to describe content of bmp image
+ Resources.
+ """
+
+ _BMP_BITS_PER_PIXEL_OFFSET_ = int('0x1C', 16)
+
+ def __init__(self, resource, data):
+ ContentInfo.__init__(self, 'image', 'bmp')
+
+ #: Color depth as bits per pixel.
+ self.color_depth = None
+ if (resource != None):
+ try:
+ self.color_depth = ord(data[self._BMP_BITS_PER_PIXEL_OFFSET_])
+ except Exception, e:
+ self.logger.warning("Invalid BMP-file: %s" % resource.get_path())
+
+class Folder(object):
+ """
+ A Folder object is a subfolder of a Storage, offering access to part of the Storages resources.
+ """
+ def __init__(self, storage, path):
+ """
+ Create a layer folder to the storage if it does not exist.
+ """
+ #if not storage.is_folder(path):
+ # storage.create_folder(path)
+ self.storage = copy.copy(storage)
+ self.storage.set_current_path(path)
+
+ def __getattr__(self, name):
+ return getattr(self.storage, name)
+
+class CompositeLayer(object):
+ """
+ A base class for composite Configuration objects.
+ """
+ def __init__(self, path="", **kwargs):
+ self.layers = kwargs.get('layers', [])
+ self.path = path
+
+ def add_layer(self, layer):
+ self.layers.append(layer)
+
+ def remove_layer(self, path):
+ if self.get_layer(path):
+ self.layers.remove(self.get_layer(path))
+ else:
+ raise exceptions.NotFound('Layer with given path %s not found!' % path)
+
+ def get_layer(self, path):
+ for layer in self.layers:
+ if layer.get_current_path() == path:
+ return layer
+ return None
+
+ def list_layers(self):
+ return [layer.get_current_path() for layer in self.layers]
+
+ def list_confml(self):
+ """
+ @return: array of confml file references.
+ """
+ lres = []
+ for layerpath in self.list_layers():
+ for respath in self.get_layer(layerpath).list_confml():
+ lres.append(utils.resourceref.join_refs([layerpath, respath]))
+ return lres
+
+ def list_implml(self):
+ """
+ @return: array of implml file references.
+ """
+ lres = []
+ for layerpath in self.list_layers():
+ for respath in self.get_layer(layerpath).list_implml():
+ lres.append(utils.resourceref.join_refs([layerpath, respath]))
+ return lres
+
+ def list_content(self):
+ """
+ @return: array of content file references.
+ """
+ lres = []
+ for layerpath in self.list_layers():
+ for respath in self.get_layer(layerpath).list_content():
+ lres.append(utils.resourceref.join_refs([layerpath, respath]))
+ return lres
+
+ def list_doc(self):
+ """
+ @return: array of document file references.
+ """
+ lres = []
+ for layerpath in self.list_layers():
+ for respath in self.get_layer(layerpath).list_doc():
+ lres.append(utils.resourceref.join_refs([layerpath, respath]))
+ return lres
+
+ def list_all_resources(self, empty_folders=False):
+ """
+ Returns a list of all layer related resource paths with full path in the storage.
+ """
+ lres = []
+ for layerpath in self.list_layers():
+ sublayer = self.get_layer(layerpath)
+ for respath in sublayer.list_all_resources(empty_folders):
+ lres.append(utils.resourceref.join_refs([layerpath, respath]))
+
+ return lres
+
+class Layer(CompositeLayer):
+ """
+ A Layer object is a subfolder of a Storage, offering access to part of the Storages resources.
+ """
+ def __init__(self, storage, path, **kwargs):
+ """
+ Create a layer folder to the storage if it does not exist.
+ @param storage: a reference to the Storage object
+ @param path: path for the layer
+ @param confml_path: optional parameter for confml files path (give in confml_path="something")
+ @param imlpml_path: optional parameter for implml files path (give in implml_path="something")
+ @param content_path: optional parameter for content files path (give in content_path="something")
+ @param doc_path: optional parameter for doc files path (give in doc_path="something")
+ """
+ super(Layer, self).__init__(path, **kwargs)
+ #if not storage.is_folder(path):
+ # storage.create_folder(path)
+ self.storage = copy.copy(storage)
+ self.storage.set_current_path(path)
+ self.predefined = {'confml_path' : 'confml',
+ 'implml_path' : 'implml',
+ 'content_path' : 'content',
+ 'doc_path' : 'doc'}
+ # list through all "hardcoded" paths and check whether the
+ # hardcoded or given path exists under this Layer.
+ # if it does then create a folder instance to that path
+ for (pretag, prevalue) in self.predefined.items():
+ self.predefined[pretag] = kwargs.get(pretag, prevalue)
+
+ def __getattr__(self, name):
+ return getattr(self.storage, name)
+
+ def list_confml(self):
+ """
+ @return: array of confml file references.
+ """
+ res = self.storage.list_resources(self.predefined['confml_path'], True)
+ res += super(Layer, self).list_confml()
+ return res
+
+ def list_implml(self):
+ """
+ @return: array of implml file references.
+ """
+ res = self.storage.list_resources(self.predefined['implml_path'], True)
+ res += super(Layer, self).list_implml()
+ return res
+
+ def list_content(self):
+ """
+ @return: array of content file references.
+ """
+ res = self.storage.list_resources(self.predefined['content_path'], True)
+ res += super(Layer, self).list_content()
+ return res
+
+ def list_doc(self):
+ """
+ @return: array of document file references.
+ """
+ res = self.storage.list_resources(self.predefined['doc_path'], True)
+ res += super(Layer, self).list_doc()
+ return res
+
+ def confml_folder(self):
+ cpath = self.storage.get_current_path()
+ spath = self.predefined['confml_path']
+ return Folder(self.storage, utils.resourceref.join_refs([cpath, spath]))
+
+ def implml_folder(self):
+ cpath = self.storage.get_current_path()
+ spath = self.predefined['implml_path']
+ return Folder(self.storage, utils.resourceref.join_refs([cpath, spath]))
+
+ def content_folder(self):
+ cpath = self.storage.get_current_path()
+ spath = self.predefined['content_path']
+ return Folder(self.storage, utils.resourceref.join_refs([cpath, spath]))
+
+ def doc_folder(self):
+ cpath = self.storage.get_current_path()
+ spath = self.predefined['doc_path']
+ return Folder(self.storage, utils.resourceref.join_refs([cpath, spath]))
+
+ def list_all_resources(self, empty_folders=False):
+ """
+ Returns a list of all layer related resource paths with full path in the storage.
+ """
+ lres = []
+ mypath = self.get_current_path()
+
+ for folderpath in sorted(self.predefined.values()):
+ lres += self.storage.list_resources(folderpath, recurse=True, empty_folders=empty_folders)
+
+ lres += super(Layer, self).list_all_resources(empty_folders)
+
+ return lres
+
+ def list_all_related(self, empty_folders=False):
+ """
+ Returns a list of all (non confml) layer related resource paths with full path in the storage.
+ """
+ lres = []
+ predef = self.predefined.copy()
+ del predef['confml_path']
+ mypath = self.get_current_path()
+ for folderpath in sorted(predef.values()):
+ lres += self.storage.list_resources(folderpath, recurse=True, empty_folders=empty_folders)
+ lres += super(Layer, self).list_all_resources(empty_folders=empty_folders)
+
+ return lres
+
+
+class Rule(object):
+ """
+ Base class for Rules in the system.
+ """
+ def __init__(self):
+ raise exceptions.NotSupportedException()
+
+
+class FactoryBase(object):
+ pass
+
+class Factory(object):
+ def __getattr__(self, name):
+ """
+ The Factory getattr find all subclasses for the Factory and searches for given attr
+ in those.
+ """
+ for sub_factory in utils.all_subclasses(FactoryBase):
+ try:
+ return getattr(sub_factory(), name)
+ except AttributeError:
+ continue
+ raise AttributeError("type object %s has no attribute '%s'" % (self.__class__, name))
+
+def get_mapper(modelname):
+ """
+ Return a instance of appropriate mapper for given model.
+ """
+ mapmodule = __import__('cone.public.mapping')
+ return mapmodule.public.mapping.BaseMapper()
+
+
+##################################################################
+class NullHandler(logging.Handler):
+ """
+ Default handler that does not do anything.
+ """
+ def emit(self, record):
+ pass
+
+#Initialization of default logger that contains NullHandler.
+logger = logging.getLogger('cone')
+logger.addHandler(NullHandler())
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/container.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/container.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,794 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Container classes.
+Mainly internal classed that the public data model uses internally.
+"""
+
+import re
+import pickle
+import logging
+import utils, exceptions
+
+def object_container_filter(obj,**kwargs):
+ """ Create a list of filter functions for each argument """
+ filters=[]
+ if kwargs.has_key('name'):
+ filters.append(lambda x: re.match(kwargs.get('name'), x._name))
+ if kwargs.has_key('path'):
+ filters.append(lambda x: re.match(kwargs.get('path'), x._path()))
+ if kwargs.has_key('type'):
+ filters.append(lambda x: isinstance(x, kwargs.get('type')))
+ if kwargs.has_key('filters'):
+ filters += kwargs.get('filters')
+ ret = []
+ for sobj in utils.get_list(obj):
+ if utils.filter(obj,filters):
+ ret.append(sobj)
+
+ return ret
+
+def _apply_filter(obj,filters):
+ """ Create a list of filter functions for each argument """
+ if utils.filter(obj,filters):
+ return [obj]
+ else:
+ return []
+
+""" object container adding policies """
+REPLACE = 0
+APPEND = 1
+PREPEND = 2
+ERROR = 3
+
+class DataContainer(object):
+ """
+ Class for data containers.
+ Container is a data storage that can hold several keys, where each key is unique. Each key however
+ can hold several values, where the active value is the last one added.
+
+ Example:
+ data = {'key1' :[1,2,3,4],
+ 'key2' :['foo','bar],
+ 'key3' :['testing'],
+ 'path/to/key' :['some','value','in','here','too']}
+
+ The active values for keys are the last ones in the array. E.g. key1 = 4.
+ """
+ def __init__(self):
+ self.data = {}
+
+ def list_keys(self):
+ """
+ List all keys of the DataStorage.
+ """
+ return self.data.keys()
+
+ def add_value(self,key,value):
+ """
+ Add the value as a topmost item for the given key.
+ @param key: name for the key to store the data.
+ @param value: the value to store.
+ """
+ if self.data.has_key(key):
+ self.data[key].append(value)
+ else:
+ self.data[key] = [value]
+ return
+
+ def remove_value(self,key,value):
+ """
+ remove individual value of the key value array
+ """
+ self.data[key].remove(value)
+ return
+
+ def remove_key(self,key):
+ del self.data[key]
+ return
+
+ def get_value(self,key):
+ """
+ self.data = {'key1' :[1,2,3,4],
+ 'key2' :['foo','bar],
+ 'key3' :['testing'],
+ 'path/to/key' :['some','value','in','here','too']}
+ self.get_value('key1')
+ 4
+ """
+ return self.data[key][-1]
+
+ def get_values(self,key):
+ """
+ return a copy of data values inside the container
+ """
+ values = []
+ values.extend(self.data[key])
+ return values
+
+ def flatten(self):
+ """
+ return a new dictionary of the DataContainer data with only single values for each key,
+ instead of the array of values.
+ """
+ rest = {}
+ for key in self.data.keys():
+ rest[key] = self.get_value(key)
+ return rest
+
+ def clear(self):
+ """
+ Remove all data from the container.
+ """
+ return self.data.clear()
+
+class ContainerBase(object):
+
+ def _set_parent(self, newparent):
+ """
+ @param newparent: The new parent object
+ @return: None
+ """
+ self._parent = newparent
+
+ def _get_parent(self):
+ """
+ @return: existing parent object
+ """
+ return self._parent
+
+ def _del_parent(self):
+ """
+ Set the current parent to None
+ """
+ self._parent = None
+
+ parent = property(_get_parent, _set_parent,_del_parent)
+
+
+class ObjectProxy(ContainerBase):
+ """
+ An object proxy class. The ObjectProxy overrides the python builtin methdo __getattr__
+ to redirect any function/member access to the subobject.
+ """
+ def __init__(self,obj=None):
+ """
+ """
+ self._obj = obj
+ self._parent = None
+
+ def __getattr__(self,name):
+ """
+ direct all not found attribute calls to the sub object getattr
+ """
+ return getattr(self._obj,name)
+
+
+# def _set_parent(self, newparent):
+# """
+# @param newparent: The new parent object
+# @return: None
+# """
+# self._parent = newparent
+# if isinstance(self._obj, ContainerBase):
+# self._obj._set_parent(newparent)
+
+class LoadInterface(ContainerBase):
+ def load(self,ref):
+ file = open(ref,"r")
+ self._parent = None
+ return pickle.load(file)
+
+ def unload(self,ref, obj):
+ """
+ unload or release
+ """
+ file = open(ref,"w")
+ pickle.dump(obj,file)
+ file.close()
+
+ def get_path(self):
+ """
+ Return the path of the configuration resource
+ """
+ return ""
+
+class LoadProxy(ContainerBase):
+ """
+ This class is meant for loading & unloading an object, when it need.
+ """
+ def __init__(self, path, store_interface=None):
+ """
+ @param path: the path which is used in loadin
+ @param store_interface: the loading interface object, which is used.
+ Expects load(path) and dump(obj) functions
+ """
+ self.set('_obj', None)
+ self.set('_parent', None)
+ self.set('path', path)
+ self.set('_storeint', store_interface)
+
+ def __getattr__(self,name):
+ """
+ direct all not found attribute calls to the sub object getattr
+ """
+ if not self._obj:
+ self._load()
+ return getattr(self._obj,name)
+
+ def __setattr__(self, name, value):
+ """
+ direct attribute setting calls to the sub object setattr
+ """
+ if not self._obj:
+ self._load()
+ setattr(self._obj,name,value)
+
+ def __delattr__(self, name):
+ """
+ direct attribute setting calls to the sub object setattr
+ """
+ if not self._obj:
+ self._load()
+ delattr(self._obj,name)
+
+ def _set_parent(self, newparent):
+ """
+ @param newparent: The new parent object
+ @return: None
+ """
+ self.set('_parent',newparent)
+ if self._obj:
+ self._obj._parent = self._parent
+
+ def _set_obj(self, obj):
+ self.set('_obj',obj)
+ # set the same _parent for the actual object as is stored for the proxy
+ self._obj._parent = self._parent
+ self._obj.set_path(self.path)
+
+ def _get_obj(self):
+ if not self._obj:
+ self._load()
+ return self._obj
+
+ def _load(self):
+ # Should the loading of layer external resources be supported?
+ # E.g. resources with absolute path relative to the storage (starts with slash)
+ """ If the loading of the object fails => Raise an InvalidObject exception """
+ try:
+ obj = self._store_interface().load(self.fullpath)
+ self._set_obj(obj)
+ obj.set_ref(utils.resourceref.to_objref(self.path))
+ except exceptions.NotResource,e:
+ logging.getLogger('cone').warning("Loading %s from parent %s failed! %s" % (self.path,self.get_parent_path(), e))
+ raise exceptions.InvalidObject("Invalid configuration object %s" % self.path)
+
+ def _unload(self):
+ if self._obj:
+ self._store_interface().unload(self.fullpath, self._obj)
+ self.set('_obj',None)
+
+ def _store_interface(self):
+ if not self._storeint:
+ self.set('_storeint',self._parent.get_project())
+ return self._storeint
+
+ def set(self,name,value):
+ """
+ Proxy has a specific attribute setting function, because by default all attributes are
+ stored to the actual proxy object
+ """
+ self.__dict__[name] = value
+
+ def get(self,name):
+ """
+ Proxy has also a specific attribute getting function, because by default all attributes are
+ stored to the actual proxy object
+ """
+ return self.__dict__[name]
+
+ def save(self):
+ if hasattr(self._obj,'save'):
+ self._obj.save()
+ self._unload()
+
+ def close(self):
+ if hasattr(self._obj,'close'):
+ self._obj.close()
+
+ def get_parent_path(self):
+ """
+ Return the path of the configuration resource
+ """
+ if self._parent:
+ return utils.resourceref.get_path(self._parent.get_path())
+ else:
+ return ""
+
+ def get_path(self):
+ """
+ Return the path of the configuration resource
+ """
+ if self._obj:
+ return self._obj.get_path()
+ else:
+ return self.path
+
+ @property
+ def fullpath(self):
+ """
+ Return the path of the configuration resource
+ """
+ try:
+ return self._obj.get_full_path()
+ except AttributeError:
+ parent_path = self.get_parent_path()
+ return utils.resourceref.join_refs([parent_path,self.path])
+
+class ObjectContainer(ContainerBase):
+ """
+ An object container class. The ObjectContainer is actually a Tree data structure. Any ObjectContainer
+ instance can include any number of children, that must be instances of ObjectContainer.
+ """
+ def __init__(self,name="",**kwargs):
+ """
+ """
+ if len(name.split(".")) > 1 or len(name.split("/")) > 1:
+ raise exceptions.InvalidRef("Illegal name for ObjectContainer %s" % name)
+ self._name = name
+ self._parent = None
+ self._order = []
+ self._children = {}
+ for arg in kwargs.keys():
+ setattr(self, arg, kwargs.get(arg))
+
+ def __getattr__(self,name):
+ """
+ direct all not found attribute calls to the sub object getattr
+ """
+ try:
+ return self.__dict__['_children'][name]
+ except KeyError:
+ return getattr(super(ObjectContainer),name)
+
+ def _path(self, toparent=None):
+ """
+ Get the path to this ObjectContainer.
+ @param toparent: the _parent object up to which the path is relative. Default value is None.,
+ which gives the fully qualified path
+ @return: The path to the ObjectContainer from toparent
+ """
+ if self == toparent:
+ return ""
+ elif self._parent and self._parent != toparent:
+ # return the path with list index if the given element is in a list
+ if utils.is_list(self.parent._get(self._name)):
+ return self._parent._path(toparent)+"."+"%s[%s]" % (self._name,self.get_index())
+ else:
+ return self._parent._path(toparent)+"."+self._name
+ else:
+ return self._name
+
+ def _add(self, child, policy=REPLACE):
+ """
+ Add a child object.
+ @param child: The child object to add. The child needs to be an instance of ObjectContainer.
+ @param policy: The policy which is used when an object with same name exists already
+ """
+ # check that the child is a supported type
+ if not self._supported_type(child):
+ raise exceptions.IncorrectClassError("Cannot add instance of %s to %s." % (child.__class__,self.__class__))
+ if policy == REPLACE:
+ self._replace(child)
+ elif policy == ERROR:
+ self._error(child)
+ elif policy == APPEND:
+ self._append(child)
+ elif policy == PREPEND:
+ self._prepend(child)
+
+ def _append(self, child):
+ """
+ Add the given child to the proper key. Create a list entry if necessary
+ """
+ child._set_parent(self)
+ if not self._children.has_key(child._name):
+ # skip all internal objects (that start with _)
+ if not child._name.startswith('?'):
+ self._order.append(child._name)
+ self._children[child._name] = child
+ else:
+ """ Create a list under the child name """
+ self._children[child._name] = utils.add_list(self._children[child._name], child)
+ return
+
+ def _prepend(self, child):
+ """
+ Add the given child to the proper key. Create a list entry if necessary
+ """
+ child._set_parent(self)
+ if not self._children.has_key(child._name):
+ # skip all internal objects (that start with _)
+ if not child._name.startswith('?'):
+ self._order.insert(0,child._name)
+ self._children[child._name] = child
+ else:
+ """ Create a list under the child name """
+ self._children[child._name] = utils.prepend_list(self._children[child._name], child)
+ return
+
+ def _replace(self, child):
+ """
+ If the given child already exists => Replace the child,
+ but maintain the current children of that child
+ """
+ child._set_parent(self)
+ # skip all internal objects (that start with _)
+ if not self._children.has_key(child._name):
+ if not child._name.startswith('?'):
+ self._order.append(child._name)
+ else:
+ """ if the existing child is a instance of ObjectContainer,
+ add all children of the existing contianer to this new object """
+ existingchild = self._children[child._name]
+ if isinstance(existingchild, ObjectContainer):
+ for subchild in existingchild._objects():
+ child._add(subchild)
+
+ self._children[child._name] = child
+ return
+
+ def _error(self, child):
+ """
+ If the given child already exists => raise an exception.
+ @raise exceptions.AlreadyExists:
+ """
+ child._set_parent(self)
+ if not self._children.has_key(child._name):
+ # skip all internal objects (that start with _)
+ if not child._name.startswith('?'):
+ self._order.insert(0,child._name)
+ self._children[child._name] = child
+ else:
+ raise exceptions.AlreadyExists('Child %s already exists' % child._name)
+ return
+
+ def _add_to_path(self, path, child, policy=REPLACE):
+ """
+ Add a child object.
+ @param path: the path for the object
+ @param child: The child object to add
+ @param namespace: The namespace of the object, which defines where the object is created
+ """
+ # check that the child is a supported type
+ if not self._supported_type(child):
+ raise exceptions.IncorrectClassError("Cannot add instance of %s to %s Container" % (child.__class__,self.__class__))
+ # ensure that the elements to the namespace exist
+ curelem = self
+ for ppath in utils.dottedref.split_ref(path):
+
+ if not curelem._children.has_key(ppath):
+ # Create missing elem
+ curelem._add(self._default_object(ppath))
+ curelem = curelem._get(ppath)
+ curelem._add(child,policy)
+
+ def _get(self, path):
+ """
+ Get a child object by it path.
+ @return: The child object if it is found.
+ @raise NotFound: when object is not found from the children.
+ """
+
+ try:
+ # traverse to the actual child element
+ curelem = self
+ for pathelem in utils.dottedref.split_ref(path):
+ if utils.dottedref.get_index(pathelem) == None:
+ curelem = curelem._children[pathelem]
+ else:
+ # If the given pathelem is referring to a list
+ name = utils.dottedref.get_name(pathelem)
+ index = utils.dottedref.get_index(pathelem)
+ curelem = utils.get_list(curelem._children[name])[index]
+ return curelem
+ # Catch the KeyError exception from dict and IndexError from list
+ except (KeyError,IndexError):
+ raise exceptions.NotFound("Child %s not found!" % path)
+
+ def _has(self, path):
+ """
+ Returns True if an element under the path is found.
+ @return: Boolean value.
+ """
+
+ try:
+ # traverse to the actual child element
+ curelem = self
+ for pathelem in utils.dottedref.split_ref(path):
+ curelem = curelem._children[pathelem]
+ return True
+ except KeyError:
+ return False
+
+ def _remove(self, path):
+ """
+ Remove a child object by it path.
+ """
+ # if the patherence is a long patherence (dotted name)
+ # first get the _parent object and call the remove to the _parent
+ (parentref,name) = utils.dottedref.psplit_ref(path)
+ if parentref != "":
+ self._get(parentref)._remove(name)
+ elif utils.dottedref.get_index(path) != None and \
+ self._get(utils.dottedref.get_name(path)):
+ # Delete If the given pathelem is referring to a list
+ name = utils.dottedref.get_name(path)
+ index = utils.dottedref.get_index(path)
+ del self._children[name][index]
+ if len(self._children[name]) == 0:
+ del self._order[self._order.index(name)]
+ elif self._get(path) != None: # delete if the child is found
+ del self._children[path]
+ del self._order[self._order.index(path)]
+
+ else:
+ raise exceptions.NotFound("Child %s not found!" % path)
+
+ def _list_traverse(self,**kwargs):
+ """
+ Return a list of all children paths. This function calls internally __traverse__, see it for
+ more details.
+ @return: an unordered list of children paths. The path is relative to this node.
+ """
+ return [child._path(self) for child in self._traverse(**kwargs)]
+
+ def _traverse(self, **kwargs):
+ """
+ The traverse goes recursively through the tree of children of this node and returns a result set as list.
+ Arguments can be passed to it to filter out elements of the result set. All arguments are
+ given as dict, so they must be given with name. E.g. _traverse(name='test')
+ @param name: The node name or part of name which is used as a filter. This is a regular expression (uses internally re.match())
+ @param path: The path name or part of name which is used as a filter. This is a regular expression (uses internally re.match())
+ @param filters: A list of predefined filters can be given as lambda functions. E.g. filters=[lambda x: isinstance(x._obj, FooClass)]
+ @return: a list of ObjectContainer objects.
+ """
+ filterlist=[]
+ if kwargs.has_key('ref'):
+ filterlist.append(lambda x: re.match(kwargs.get('ref'), x.ref))
+ if kwargs.has_key('name'):
+ filterlist.append(lambda x: re.match(kwargs.get('name'), x._name))
+ if kwargs.has_key('path'):
+ filterlist.append(lambda x: re.match(kwargs.get('path'), x._path()))
+ if kwargs.has_key('type'):
+ filterlist.append(lambda x: isinstance(x, kwargs.get('type')))
+ if kwargs.has_key('filters'):
+ filterlist += kwargs.get('filters')
+
+ ret = []
+ for child in self._objects():
+ subchildren = child._tail_recurse(_apply_filter,filters=filterlist)
+ ret += subchildren
+ return ret
+
+ def _find_leaves(self, **kwargs):
+ """
+ Find all leaf nodes in the tree that satisfy the given filtering criteria.
+
+ For possible keyword arguments see _traverse().
+
+ @return: A list of ObjectContainer objects.
+ """
+ # Find all children
+ nodes = self._traverse(**kwargs)
+
+ # Filter out non-leaves
+ return filter(lambda node: len(node._objects()) == 0, nodes)
+
+ def _tail_recurse(self, function, **kwargs):
+ """
+ Run a tail recursion on all container children and execute the given function.
+ 1. function will receive self as argument to it.
+ 2. function will receive all kwargs as argument to it.
+ 3. tail recursion means that the function is executed first and then the
+ recursion continues.
+ @param function: the function which is executed
+ @param kwargs: a list of arguments as dict
+ @return: an list of objects, which can be anything that the funtion returns
+ """
+
+ ret = []
+ ret += function(self,**kwargs)
+ for child in self._objects():
+ try:
+ # We wont add the object to the ret until we know that it is a valid object
+ subchildren = child._tail_recurse(function,**kwargs)
+ #ret += function(child,**kwargs)
+ ret += subchildren
+ except exceptions.InvalidObject,e:
+ # remove the invalid object from this container
+ logging.getLogger('cone').warning('Removing invalid child because of exception %s' % e)
+ self._remove(child._name)
+ continue
+ return ret
+
+ def _head_recurse(self, function,**kwargs):
+ """
+ Run a tail recursion on all container children and execute the given function.
+ 1. function will receive self as argument to it.
+ 2. function will receive all kwargs as argument to it.
+ 3. head recursion means that the recursion continues to the leaf nodes and then the
+ execution of the function begins.
+ @param function: the function which is executed
+ @param kwargs: a list of arguments as dict
+ @return: an list of objects, which can be anything that the funtion returns
+ """
+ ret = []
+ for child in self._objects():
+ try:
+ ret += child._head_recurse(function,**kwargs)
+ ret += function(child,**kwargs)
+ except exceptions.InvalidObject,e:
+ # remove the invalid object from this container
+ logging.getLogger('cone').warning('Removing invalid child because of exception %s' % e)
+ self._remove(child._name)
+ continue
+ return ret
+
+ def _list(self):
+ """
+ Return a array of immediate children names.
+ @return: an unordered list of immediate children path-references
+ """
+ # skip all internal objects (that start with _)
+ return [name for name in self._order if not name.startswith('?')]
+
+ def _objects(self, **kwargs):
+ """
+ Return a array of immediate children.
+ @return: an unordered list of immediate children
+ """
+ ret = []
+ for cname in self._order:
+ try:
+ if object_container_filter(self._children[cname], **kwargs):
+ ret += utils.get_list(self._children[cname])
+ except exceptions.InvalidObject,e:
+ # remove the invalid object from this container
+ logging.getLogger('cone').warning('Removing invalid child because of exception %s' % e)
+ self._remove(cname)
+ continue
+ return ret
+
+ def _get_index(self, name):
+ """
+ Get the index of a child object by its name. The index matches the index
+ of the child object in the _children array.
+ @return: integer.
+ @raise NotFound: when object is not found from the children.
+ """
+
+ try:
+ return self._order.index(name)
+ except KeyError:
+ raise exceptions.NotFound("Child %s not found!" % name)
+
+ def _supported_type(self,obj):
+ """
+ An internal function to check that the given object is a supported for this Tree.
+ This is used in every __add__ operation to check whether the object can be added to the tree.
+ This function should be overloaded by a subclass if the supported types need to be changed.
+ @return: True if object is supported, otherwise false.
+ """
+ return isinstance(obj, ObjectContainer)
+
+ def _default_object(self,name):
+ """
+ An internal function to create a default object for this container in case of __add_to_path__, which
+ creates the intermediate objects automatically.
+ This function should be overloaded by a subclass if the default object need to be changed.
+ @return: A new object.
+ """
+ return ObjectContainer(name)
+
+ def _find_parent(self, **kwargs):
+ """
+ find a _parent object by arguments. You can define any number of object attributes that
+ have to match to the object.
+ Example1:
+ _find_parent(foobar=True) searches for a _parent
+ object which has a member attribute foobar and its value is True.
+ Example2:
+ _find_parent(name="test") searches for a _parent
+ object which has a member attribute name and its value is "test".
+ Example3: type is a special case
+ _find_parent(type=Configuration) searches for a _parent
+ object which is an instance of Configuration (checked with isinstance).
+ @param kwargs:
+ @return: The object that matches the arguments
+ @raise exceptions.NotFound: When no matching parent is found
+ """
+ type = kwargs.get('type', None)
+ if hasattr(self,'_parent') and self._parent != None:
+ found = True
+ for key in kwargs.keys():
+ try:
+ # handle type as a special case
+ if key == 'type':
+ if not isinstance(self._parent, kwargs.get(key)):
+ found = False
+ break
+ elif key == 'match':
+ if not self._parent == kwargs.get(key):
+ found = False
+ break
+ elif not getattr(self._parent, key) == kwargs.get(key):
+ found = False
+ break
+ except AttributeError:
+ found = False
+ break
+ if found:
+ return self._parent
+ else:
+ return self._parent._find_parent(**kwargs)
+ else:
+ raise exceptions.NotFound("Parent not found!")
+
+ def _find_parent_or_default(self, default=None,**kwargs):
+ """
+ Calls internally the find parent function, which is encapsulated with try except
+ returns the given default value if find parent raises NotFound exception.
+ """
+ try:
+ return self._find_parent(**kwargs)
+ except exceptions.NotFound:
+ return default
+
+ def set_ref(self,ref):
+ """
+ @param ref: The new reference of the object
+ """
+ self._name = ref
+ self.ref = ref
+
+ def get_ref(self):
+ """
+ @return: The reference of the object.
+ """
+ return self.ref
+
+class ObjectProxyContainer(ObjectProxy,ObjectContainer):
+ """
+ Combines the Container and Proxy classes to one.
+ """
+ def __init__(self,obj=None,name=""):
+ """
+ """
+ ObjectContainer.__init__(self,name)
+ ObjectProxy.__init__(self,obj)
+
+ def __getattr__(self,name):
+ """
+ First check if the requested attr is a children then
+ direct all not found attribute calls to the sub object getattr
+ """
+ try:
+ return self.__dict__['_children'][name]
+ except KeyError:
+ return getattr(self._obj,name)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/exceptions.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/exceptions.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+class ConeException(Exception):
+ pass
+
+class NotSupportedException(ConeException):
+ def __init__(self, message=""):
+ self.message = "Not supported! %s" % message
+ ConeException.__init__(self, self.message)
+
+class StorageException(ConeException):
+ pass
+
+class NotResource(StorageException):
+ pass
+
+class NotFound(ConeException):
+ pass
+
+class NotBound(ConeException):
+ pass
+
+class NoParent(ConeException):
+ pass
+
+class AlreadyExists(ConeException):
+ pass
+
+class ConePersistenceError(ConeException):
+ pass
+
+class ParseError(ConeException):
+ """
+ Exception raised when invalid data is attempted to be parsed.
+
+ The attributes ``desc`` and ``lineno`` contain a description of
+ the error and the line on which the error occurred, if available.
+ The exception message itself may be composed of these two to make it more
+ readable, but it may also just be the same as the description.
+
+ @message: Exception message.
+ @param lineno: The line number where the error occurred. Can be None to
+ signify that the line number is not available.
+ @param desc: Error description. If None, the exception message will be
+ used here also.
+ """
+ def __init__(self, message, lineno=None, desc=None):
+ ConeException.__init__(self, message)
+ self.lineno = lineno
+ self.desc = desc or message
+
+class XmlParseError(ParseError):
+ pass
+
+class IncorrectClassError(ConeException):
+ pass
+
+class InvalidRef(ConeException):
+ pass
+
+class InvalidObject(ConeException):
+ """ This error is raised inside the ObjectContainer class when in any container
+ operation an invalid object is encountered.
+ """
+ pass
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/mapping.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/mapping.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+
+"""
+Method base for Mapping model 2 model
+"""
+
+class BaseMapper(object):
+ """
+ BaseMapper returns the object itself
+ """
+ def __init__(self):
+ pass
+
+ def map_object(self, object):
+ """
+ Return the object self
+ """
+ return object
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/persistence.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/persistence.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,97 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+from cone.public import api, exceptions
+
+
+class PersistenceFactory(api.FactoryBase):
+ @classmethod
+ def get_reader_for_elem(cls,elemname):
+ for reader in ConeReader.__subclasses__():
+ if reader.supported_elem(elemname):
+ return reader()
+ raise exceptions.ConePersistenceError("No reader for given elemname %s found!" % elemname)
+
+ @classmethod
+ def get_writer_for_class(cls,classname):
+ for writer in ConeWriter.__subclasses__():
+ if writer.supported_class(classname):
+ return writer ()
+ raise exceptions.ConePersistenceError("No writer for given class found!")
+
+
+class ConeHandler(object):
+ ext = ""
+ class_type = ""
+
+
+class ConeReader(ConeHandler):
+ '''
+ Read data from the string and return a ConeObject
+ '''
+
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConeReader supports reading
+ of the given element name
+ """
+ return False
+
+ def loads(self,data):
+ raise exceptions.NotSupportedException()
+
+ def load(self,res):
+ raise exceptions.NotSupportedException()
+
+
+class ConeWriter(object):
+ '''
+ Write a ConeObject to a string
+ '''
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConeWriter supports writing
+ of the given class name
+ """
+ return False
+
+ def dumps(self,ConeObject):
+ raise exceptions.NotSupportedException()
+
+ def dump(self,ConeObject,res,indent=True):
+ raise exceptions.NotSupportedException()
+
+def indent(elem, level=0):
+ i = os.linesep + level*" "
+ if len(elem):
+ try:
+ if not elem.text or not elem.text.strip():
+ elem.text = i + " "
+ for e in elem:
+ indent(e, level+1)
+ if not e.tail or not e.tail.strip():
+ e.tail = i + " "
+ if not e.tail or not e.tail.strip():
+ e.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
+ except AttributeError,e:
+ # explanation for this kind of try-except required
+ pass
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1580 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+import sys
+import os
+import re
+import logging
+import sets
+import inspect
+import xml.parsers.expat
+
+from cone.public import exceptions, utils, api, container, settings, rules
+import _plugin_reader
+
+debug = 0
+"""
+Implementation specific settings can be overriden in the global impl_settings variable
+"""
+
+AUTOCONFIG_CONFML = "autodata.confml"
+
+def get_autoconfig(configuration):
+ """
+ Return the "automatic" configuration for storing temporary run-time ConfML
+ features and values.
+ """
+ lastconfig = configuration.get_last_configuration()
+ if lastconfig.get_path() != AUTOCONFIG_CONFML:
+ logging.getLogger('cone').debug('Adding autodata configuration %s' % AUTOCONFIG_CONFML)
+ configuration.create_configuration(AUTOCONFIG_CONFML)
+
+ lastconfig = configuration.get_last_configuration()
+ assert lastconfig.get_path() == AUTOCONFIG_CONFML
+ return lastconfig
+
+def get_supported_file_extensions():
+ """
+ Return a list of all supported ImplML file extension.
+
+ Implementations are only attempted to be read from files with these
+ extensions.
+ """
+ return ImplFactory.get_supported_file_extensions()
+
+def get_supported_namespaces():
+ """
+ Returns a list of all supported ImplML namespaces.
+ """
+ return ImplFactory.get_reader_dict().keys()
+
+def is_temp_feature(feature):
+ """
+ Return whether the given feature is a temporary feature.
+ """
+ return hasattr(feature, _plugin_reader.TEMP_FEATURE_MARKER_VARNAME)
+
+class GenerationContext(object):
+ """
+ Context object that can be used for passing generation-scope
+ data to implementation instances.
+ """
+
+ def __init__(self, tags={}):
+ #: The tags used in this generation context
+ #: (i.e. the tags passed from command line)
+ self.tags = tags
+
+ #: The tags policy used in this generation context
+ self.tags_policy = "OR"
+
+ #: A dictionary that implementation instances can use to
+ #: pass any data between each other
+ self.impl_data_dict = {}
+
+ #: A string for the phase of the generation
+ self.phase = ""
+
+ #: a list of rule results
+ self.results = []
+
+ #: a pointer to the configuration
+ self.configuration = None
+
+ def eval(self, ast, expression, value):
+ """
+ eval for rule evaluation against the context
+ """
+ pass
+
+ def handle_terminal(self, expression):
+ """
+ Handle a terminal object
+ """
+ try:
+ if isinstance(expression, str):
+ m = re.match("\${(.*)}", expression)
+ if m:
+ try:
+ dview = self.configuration.get_default_view()
+ return dview.get_feature(m.group(1)).value
+ except Exception, e:
+ logging.getLogger('cone').error("Could not dereference feature %s. Exception %s" % (expression, e))
+ raise e
+ elif expression in ['true','1','True']:
+ return True
+ elif expression in ['false','0','False']:
+ return False
+ else:
+ try:
+ return eval(expression)
+ except NameError:
+ # If the expression is a string in it self it can be returned
+ return expression
+ else:
+ return expression
+ except Exception,e:
+ logging.getLogger('cone').error("Exception with expression %s: %s" % (expression, e))
+ raise e
+
+
+class FlatComparisonResultEntry(object):
+ """
+ Class representing a result entry for a flat implementation
+ comparison.
+
+ Contains the following members:
+ Member Description
+ file Implementation file
+ impl_type Implementation type (e.g. 'crml', 'gcfml')
+ id Entry ID (e.g. CRML repository UID)
+ sub_id Entry sub-ID if applicable (e.g. CRML key UID)
+ value_id Implementation-specific value identifier
+ source_value Value in the source implementation
+ target_value Value in the target implementation
+
+ data Any extra data (implementation-specific)
+ """
+
+ VARNAMES = ['file', 'impl_type', 'id', 'sub_id', 'value_id', 'source_value', 'target_value']
+
+ def __init__(self, **kwargs):
+ for varname in self.VARNAMES:
+ setattr(self, varname, kwargs.get(varname))
+ self.data = kwargs.get('data')
+
+ def __repr__(self):
+ var_entries = []
+ for varname in self.VARNAMES:
+ var_entries.append('%s=%r' % (varname, getattr(self, varname)))
+ return "FlatComparisonResultEntry(%s)" % ', '.join(var_entries)
+
+ def __eq__(self, other):
+ if type(self) is not type(other):
+ return False
+ for varname in self.VARNAMES:
+ if getattr(self, varname) != getattr(other, varname):
+ return False
+ return True
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __lt__(self, other):
+ for varname in self.VARNAMES:
+ self_val = getattr(self, varname)
+ other_val = getattr(other, varname)
+ if self_val < other_val: return True
+ elif self_val == other_val: pass
+ else: return False
+ return False
+
+class DuplicateImplementationEntry(object):
+ """
+ Class representing an entry of duplicate implementation instances
+ found in a comparison.
+ """
+ VARNAMES = ['impl_type', 'id', 'files_in_source', 'files_in_target']
+
+ def __init__(self, **kwargs):
+ self.impl_type = kwargs.get('impl_type')
+ self.id = kwargs.get('id')
+ self.files_in_source = kwargs.get('files_in_source', [])
+ self.files_in_target = kwargs.get('files_in_target', [])
+
+ def __repr__(self):
+ var_entries = []
+ for varname in self.VARNAMES:
+ val = getattr(self, varname)
+ if isinstance(val, list): val = sorted(val)
+ var_entries.append('%s=%r' % (varname, val))
+ return "DuplicateImplementationEntry(%s)" % ', '.join(var_entries)
+
+ def __eq__(self, other):
+ if type(self) is not type(other):
+ return False
+ return self.impl_type == other.impl_type \
+ and self.impl_type == other.impl_type \
+ and sorted(self.files_in_source) == sorted(other.files_in_source) \
+ and sorted(self.files_in_target) == sorted(other.files_in_target)
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __lt__(self, other):
+ for varname in self.VARNAMES:
+ self_val = getattr(self, varname)
+ other_val = getattr(other, varname)
+ if isinstance(self_val, list): self_val = sorted(self_val)
+ if isinstance(other_val, list): other_val = sorted(other_val)
+ if self_val < other_val: return True
+ elif self_val == other_val: pass
+ else: return False
+ return False
+
+class FlatComparisonResult(object):
+ """
+ Class representing a flat comparison result.
+
+ Each member is a list of FlatComparisonResultEntry
+ objects, except for 'duplicate', which contains
+ DuplicateImplementationEntry objects.
+
+ Note that the entry members 'value_id', 'source_value' and
+ 'target_value' are irrelevant in the 'only_in_source' and
+ 'only_in_target' lists, and will always be None.
+ """
+ def __init__(self, **kwargs):
+ self.only_in_source = kwargs.get('only_in_source', [])
+ self.only_in_target = kwargs.get('only_in_target', [])
+ self.modified = kwargs.get('modified', [])
+ self.duplicate = kwargs.get('duplicate', [])
+
+
+ def extend(self, other):
+ """
+ Extend this comparison result with another one.
+ """
+ if not isinstance(other, FlatComparisonResult):
+ raise ValueError("Expected instance of %s" % FlatComparisonResult.__name__)
+
+ self.only_in_source.extend(other.only_in_source)
+ self.only_in_target.extend(other.only_in_target)
+ self.modified.extend(other.modified)
+
+ def __repr__(self):
+ data = ["FlatComparisonResult(\n"]
+
+ def get_list_data(lst):
+ if len(lst) == 0: return '[]'
+
+ temp = ['[\n']
+ for item in sorted(lst):
+ temp.append(" %r\n" % item)
+ temp.append(' ]')
+ return ''.join(temp)
+
+ entries = []
+ for varname in ('only_in_source', 'only_in_target', 'modified', 'duplicate'):
+ entry_text = ' %s = %s' % (varname, get_list_data(getattr(self, varname)))
+ entries.append(entry_text)
+ data.append(',\n'.join(entries))
+
+ data.append('\n)')
+ return ''.join(data)
+
+ def __len__(self):
+ return len(self.only_in_source) + len(self.only_in_target) + len(self.modified)
+
+ def __eq__(self, other):
+ if type(self) is not type(other):
+ return False
+ return sorted(self.only_in_source) == sorted(other.only_in_source) \
+ and sorted(self.only_in_target) == sorted(other.only_in_target) \
+ and sorted(self.modified) == sorted(other.modified) \
+ and sorted(self.duplicate) == sorted(other.duplicate)
+
+ def __ne__(self, other):
+ return not (self == other)
+
+class ImplBase(object):
+ """
+ Base class for any implementation class.
+ """
+
+ #: Identifier for the implementation type, used e.g. in .cfg files.
+ #: Should be a string like e.g. 'someml'.
+ IMPL_TYPE_ID = None
+
+ #: Defines the default invocation phase for the implementation.
+ #: The default is used if the phase is not explicitly set in the
+ #: ImplML file or manually overridden by calling set_invocation_phase()
+ DEFAULT_INVOCATION_PHASE = None
+
+ def __init__(self, ref, configuration):
+ """
+ Create a ImplBase object
+ @param ref : the ref to the Implml file resource.
+ @param configuration : the Configuration instance for the
+ configuration data.
+ """
+ self._settings = None
+ self.ref = ref
+ self.index = None
+ self.configuration = configuration
+ self._output_root = self.settings.get('output_root','output')
+ self.output_subdir = self.settings.get('output_subdir','')
+ self.plugin_output = self.settings.get('plugin_output','')
+
+ self.generation_context = None
+ self._tags = None
+ self._invocation_phase = None
+ self._tempvar_defs = []
+ self.condition = None
+ self._output_root_override = None
+
+ def _eval_context(self, context):
+ """
+ This is a internal function that returns True when the context matches to the
+ context of this implementation. For example phase, tags, etc are evaluated.
+ """
+ if context.tags and not self.has_tag(context.tags, context.tags_policy):
+ return False
+ if context.phase and not context.phase in self.invocation_phase():
+ return False
+ if self.condition and not self.condition.eval(context):
+ return False
+
+ return True
+
+ def _dereference(self, ref):
+ """
+ Function for dereferencing a configuration ref to a value in the Implementation configuration context.
+ """
+ return configuration.get_default_view().get_feature(ref).value
+
+ def _compare(self, other, dict_keys=None):
+ """
+ The plugin instance against another plugin instance
+ """
+ raise exceptions.NotSupportedException()
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ @param context: The generation context can be given as a parameter.
+ The context can contain generation specific parameters for the
+ implementation object itself or the implementation can store data to it
+ which is visible to other implementations.
+ @return:
+ """
+ raise exceptions.NotSupportedException()
+
+ def post_generate(self, context=None):
+ """
+ Called when all normal generation has been done.
+
+ @param context: The generation context can be given as a parameter.
+ The context can contain generation specific parameters for the
+ implementation object itself or the implementation can store data to it
+ which is visible to other implementations.
+ @attention: This is a temporary method used for implementing cenrep_rfs.txt generation.
+ """
+ pass
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ return []
+
+ def get_refs(self):
+ """
+ Return a list of all ConfML setting references that affect this
+ implementation. May also return None if references are not relevant
+ for the implementation.
+ """
+ return None
+
+ def has_ref(self, refs):
+ """
+ @param refs: a list of references to check against.
+ @returns True if the implementation uses the given refs as input value, return False if the ref is not found.
+ If refs are not relevant for the given plugin returns None.
+ """
+ impl_refs = self.get_refs()
+ if impl_refs is None:
+ return None
+
+ if isinstance(refs, basestring):
+ refs = [refs]
+
+ for ref in refs:
+ for impl_ref in impl_refs:
+ if ref.startswith(impl_ref):
+ if len(ref) == len(impl_ref):
+ return True
+ elif ref[len(impl_ref)] == '.':
+ return True
+ return False
+
+ def flat_compare(self, other):
+ """
+ Return a flat comparison result for two implementations.
+ @param other: The target implementation to compare against.
+ @return: A FlatComparisonResult object.
+
+ @raise exceptions.NotSupportedException(): The implementation class does not support
+ flat comparison.
+ """
+ raise exceptions.NotSupportedException()
+
+ def get_flat_comparison_id(self):
+ """
+ Return the ID used to uniquely identify this implementation instance for flat comparison.
+
+ @raise exceptions.NotSupportedException() if the implementation class does not support
+ flat comparison.
+ """
+ raise exceptions.NotSupportedException()
+
+ def get_flat_comparison_extra_data(self):
+ """
+ Return the extra data object for a flat comparison entry.
+
+ This method is called when an implementation container comparison finds an
+ implementation instance that is not in the other container.
+
+ @raise exceptions.NotSupportedException() if the implementation class does not support
+ flat comparison.
+ """
+ raise exceptions.NotSupportedException()
+
+ @classmethod
+ def get_flat_comparison_impl_type_id(cls):
+ """
+ Return the type ID used to uniquely identify the current implementation class in flat comparison.
+
+ @raise exceptions.NotSupportedException() if the implementation class does not support
+ flat comparison.
+ """
+ raise exceptions.NotSupportedException()
+
+ @property
+ def settings(self):
+ if not self._settings:
+ parser = settings.SettingsFactory.cone_parser()
+ if self.IMPL_TYPE_ID is not None:
+ section = self.IMPL_TYPE_ID.upper()
+ else:
+ section = settings.DEFAULT_SECTION
+ self._settings = settings.ConeSettings(parser, section)
+ return self._settings
+
+ @property
+ def output(self):
+ vars = {'output_root': self.output_root,'output_subdir': self.output_subdir,'plugin_output': self.plugin_output}
+ default_format = '%(output_root)s/%(output_subdir)s/%(plugin_output)s'
+ return utils.resourceref.norm(self.settings.get('output',default_format,vars))
+
+ def _get_output_root(self):
+ if self._output_root_override is not None:
+ return self._output_root_override
+ else:
+ return self._output_root
+
+ def _set_output_root(self, value):
+ self._output_root = value
+
+ output_root = property(_get_output_root, _set_output_root, None,
+ """
+ The output root directory.
+
+ Note that if set_output_root_override() has been called with a value
+ other than None, reading this property will always return that value.
+ Otherwise it works just like any other property.
+ """)
+
+ def get_tags(self):
+ if self._tags is not None:
+ tags = self._tags
+ else:
+ tags = eval(self.settings.get('plugin_tags','{}'))
+
+ # If we have a configuration, expand setting references in the tags
+ if self.configuration is not None:
+ dview = self.configuration.get_default_view()
+ expanded_tags = {}
+ for name, values in tags.iteritems():
+ exp_name = utils.expand_refs_by_default_view(name, dview)
+ exp_values = []
+ expanded_tags[exp_name] = exp_values
+ for value in values:
+ exp_value = utils.expand_refs_by_default_view(value, dview)
+ exp_values.append(exp_value)
+ return expanded_tags
+ else:
+ return tags.copy()
+
+
+ def set_tags(self, tags):
+ """
+ Override the default implementation tags.
+ @param phase: The tag dictionary to set. If None, the implementation's
+ default tags will be used.
+ """
+ self._tags = tags
+
+ def has_tag(self, tags, policy=None):
+ """
+ @param tags: a dictionary of context : tags to check agains
+ @returns True if the implementation has a matching tag.
+ Otherwise return False.
+ """
+ if (tags==None or len(tags)==0) and len(self.get_tags()) == 0:
+ return True
+ if (tags!=None and len(tags)!=0) and len(self.get_tags()) == 0:
+ return False
+
+ items = tags.iteritems()
+ self_tags = self.get_tags()
+ if policy == 'AND':
+ for (key,values) in items:
+ tagvals = self_tags.get(key, [])
+ for val in values:
+ if val not in tagvals:
+ return False
+ return True
+ else:
+ for (key,values) in items:
+ tagvals = self_tags.get(key, [])
+ for val in values:
+ if val in tagvals:
+ return True
+ return False
+
+ return False
+
+ def set_output_root(self,output):
+ """
+ Set the root directory for the output files. The output
+ @param output : path to output dir.
+ """
+ self.output_root = output
+
+ def get_output_root(self):
+ """
+ Return the current output dir.
+ """
+ return self.output_root
+
+ def set_output_root_override(self, output):
+ """
+ Set the output root override.
+ @param output: The override value. If None, the normal output root
+ value is used.
+ """
+ self._output_root_override = output
+
+ def invocation_phase(self):
+ """
+ @return: the phase name in which the plugin wants to be executed.
+ """
+ # 1. Check if overridden on implementation instance level
+ if self._invocation_phase is not None:
+ return self._invocation_phase
+ # 2. Check if overridden on implementation class level
+ elif self.DEFAULT_INVOCATION_PHASE is not None:
+ return self.DEFAULT_INVOCATION_PHASE
+ # 3. Get from settings (if all else fails fall back to 'normal'
+ else:
+ return self.settings.get('plugin_phase', 'normal')
+
+ def set_invocation_phase(self, phase):
+ """
+ Override the default invocation phase.
+ @param phase: The invocation phase to set. If None, the implementation's
+ default phase will be used.
+ """
+ self._invocation_phase = phase
+
+ def compare(self):
+ """
+ @return: the phase name in which the plugin wants to be executed.
+ """
+ return self.settings.get('plugin_phase','normal')
+
+ def get_temp_variable_definitions(self):
+ return self._tempvar_defs
+
+ def get_relation_container(self):
+ """
+ Return a relation container containing all relations from this
+ implementation instance, or None.
+ """
+ return None
+
+ def get_all_implementations(self):
+ """
+ return a list of all actual implementation which is for ImplBase object self.
+ """
+ return [self]
+
+ def __repr__(self):
+ return "%s(ref=%r, type=%r, index=%r)" % (self.__class__.__name__, self.ref, self.IMPL_TYPE_ID, self.index)
+
+
+class ImplContainer(ImplBase):
+ """
+ Acts as a container object with list functionality.
+ """
+ def __init__(self, ref, configuration):
+ ImplBase.__init__(self, ref, configuration)
+ self.impls = []
+
+ # The list functions
+ def __getattr__(self, name):
+ if hasattr(self.impls, name):
+ return self.impls.__getattribute__(name)
+
+ def __getitem__(self, key):
+ return self.impls[key]
+
+ def __setitem__(self, key, value):
+ self.impls[key] = value
+
+ def __delitem__(self, key):
+ del self.impls[key]
+
+ def __len__(self):
+ return len(self.impls)
+
+ def __iter__(self):
+ return iter(self.impls)
+
+ def generate(self, context=None):
+ """
+ Generate function for container executes generate for all sub implementations.
+ @param context: The generation context can be given as a parameter. The container
+ passes the context to its sub implementations.
+
+ @return:
+ """
+ if context:
+ if not self._eval_context(context):
+ # should we report something if we exit here?
+ return
+
+ # run generate on sub impls
+ for impl in self.impls:
+ impl.generate(context)
+
+ def get_refs(self):
+ """
+ Return a list of all ConfML setting references that affect this
+ implementation. May also return None if references are not relevant
+ for the implementation.
+ """
+ refs = []
+ for impl in self.impls:
+ subrefs = impl.get_refs()
+ if subrefs:
+ refs += subrefs
+ if refs:
+ return utils.distinct_array(refs)
+ else:
+ return None
+
+ def get_tags(self):
+ """
+ overloading the get_tags function in ImplContainer to create sum of
+ tags of all subelements of the Container
+ @return: dictionary of tags
+ """
+ tags = ImplBase.get_tags(self)
+ for impl in self.impls:
+ # Update the dict by appending new elements to the values instead
+ # of overriding
+ for key,value in impl.get_tags().iteritems():
+ tags[key] = tags.get(key,[]) + value
+ return tags
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ files = []
+ for impl in self.impls:
+ files += impl.list_output_files()
+ return utils.distinct_array(files)
+
+ def set_output_root(self,output):
+ """
+ Set the root directory for the output files. The output
+ @param output : path to output dir.
+ """
+ self.output_root = output
+ for impl in self.impls:
+ impl.set_output_root(output)
+
+ def invocation_phase(self):
+ """
+ @return: the list of phase names in which phases this container wants to be executed.
+ """
+ # use a dictionary to store phases only once
+ phases = {}
+ phases[ImplBase.invocation_phase(self)] = 1
+ for impl in self.impls:
+ # for now only get the phases from sub ImplContainer objects
+ # this is needed until the plugin phase can be overridden with the common elems
+ if isinstance(impl, ImplContainer):
+ subphases = impl.invocation_phase()
+ if isinstance(subphases, list):
+ # join the two lists as one
+ phases = phases.fromkeys(phases.keys() + subphases, 1)
+ else:
+ phases[subphases] = 1
+ return phases.keys()
+
+ def get_temp_variable_definitions(self):
+ tempvars = self._tempvar_defs[:]
+ for impl in self.impls:
+ tempvars += impl.get_temp_variable_definitions()
+ return tempvars
+
+ def get_relation_container(self):
+ """
+ Return a relation container containing all relations from this
+ container object instance, or empty relation container.
+ """
+ container = RelationContainer([], '')
+ for impl in self.impls:
+ c = impl.get_relation_container()
+ if isinstance(c, RelationContainer):
+ container.entries.append(c)
+ return container
+
+ def get_all_implementations(self):
+ """
+ return a list of all actual implementation under this container
+ """
+ actual_impls = []
+ for subimpl in self.impls:
+ actual_impls += subimpl.get_all_implementations()
+ return actual_impls
+
+
+class ReaderBase(object):
+ """
+ Base class for implementation readers.
+
+ Each reader class supports one XML namespace, from which it reads an implementation
+ instance.
+
+ The method for parsing an implementation (read_impl()) is given an ElementTree
+ XML element as the root from which to parse the implementation. The plug-in
+ machinery handles each XML file so that the correct reader class is used to read
+ the implementations from XML elements based on the namespaces.
+ """
+
+ #: The XML namespace supported by the implementation reader.
+ #: Should be something like "http://www.xyz.org/xml/1".
+ #: Can also be None, in which case the reader will not be used
+ #: (this can be useful for defining base classes for e.g. readers
+ #: for different versions of an implementation).
+ NAMESPACE = None
+
+ #: Any extra XML namespaces that should be ignored by the
+ #: implementation parsing machinery. This is useful for specifying
+ #: namespaces that are not actual ImplML namespaces, but are used
+ #: inside an implementation (e.g. XInclude)
+ IGNORED_NAMESPACES = []
+
+ #: Supported implementation file extensions.
+ #: Sub-classes can override this to add new supported file extensions
+ #: if necessary. The file extensions simply control whether implementations
+ #: are attempted to be read from a file or not.
+ #: Note that the extensions are case-insensitive.
+ FILE_EXTENSIONS = ['implml']
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, doc_root):
+ """
+ Read an implementation instance from the given element tree.
+
+ @param resource_ref: Reference to the resource in the configuration in
+ which the given document root resides.
+ @param configuration: The configuration used.
+ @param doc_root: The document root from which to parse the implementation.
+ @return: The read implementation instance, or None.
+ """
+ raise exceptions.NotSupportedException()
+
+ @classmethod
+ def _read_xml_doc_from_resource(cls, resource_ref, configuration):
+ """
+ Parse an ElementTree instance from the given resource.
+ """
+ resource = configuration.get_resource(resource_ref)
+ try:
+ try:
+ data = resource.read()
+ return utils.etree.fromstring(data)
+ except exceptions.XmlParseError, e:
+ msg = "Invalid XML in implementation file '%s'. Exception: %s" % (resource_ref, e)
+ raise e
+ finally:
+ resource.close()
+
+class ImplContainerReader(ReaderBase):
+ """
+ Reader class for reading containers inside implementation files. A container
+ is a implementation in it self that can contain a list of actual implementations.
+ """
+ NAMESPACE = "http://www.symbianfoundation.org/xml/implml/1"
+
+
+ # The reader class list loaded using ImplFactory
+ __reader_classes = None
+ __supported_file_extensions = None
+ __ignored_namespaces = None
+
+ @classmethod
+ def get_reader_classes(cls):
+ """
+ Return a dictionary of all possible implementation reader classes.
+
+ Dictionary key is the XML namespace and the value is the corresponding
+ reader class.
+ """
+ cls.__reader_classes = ImplFactory.get_reader_dict()
+ return cls.__reader_classes
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, doc_root, read_impl_count=None):
+ # The variable read_impl_count is used to keep track of the number of
+ # currently read actual implementations. It is a list so that it can be used
+ # like a pointer, i.e. functions called from here can modify the number
+ # inside it. A more elegant solution is not done here, since this is temporary
+ # and the index variable in implementation instances will be changed to line_number,
+ # which specifies the actual line on which the implementation is specified in the file
+ if read_impl_count is None: read_impl_count = [0]
+
+ ns, tag = utils.xml.split_tag_namespace(doc_root.tag)
+ if tag != "container":
+ logging.getLogger('cone').error("Error: The root element must be a container in %s" % (ns, resource_ref))
+
+ impls = []
+ reader_classes = cls.get_reader_classes()
+ namespaces = reader_classes.keys()
+ # Read first the root container object with attributes
+ # and then traverse through possible child containers
+ containerobj = ImplContainer(resource_ref, configuration)
+ containerobj.condition = cls.get_condition(doc_root)
+
+ common_data = _plugin_reader.CommonImplmlDataReader.read_data(doc_root)
+
+ # traverse through the subelements
+ for elem in doc_root:
+ ns, tag = utils.xml.split_tag_namespace(elem.tag)
+ if ns == cls.NAMESPACE:
+ # Read a sub-container from the common namespace (all other
+ # common namespace elements were handled earlier)
+ if tag == "container":
+ subcontainer = cls.read_impl(resource_ref, configuration, elem, read_impl_count=read_impl_count)
+ containerobj.append(subcontainer)
+ subcontainer.index = None # For now all sub-containers have index = None
+ else:
+ # Try to read the sub implementation object from some other namespace
+ if ns not in namespaces:
+ logging.getLogger('cone').error("Error: no reader for namespace '%s' in %s" % (ns, resource_ref))
+ else:
+ reader = reader_classes[ns]
+ subelem = reader.read_impl(resource_ref, configuration, elem)
+ if common_data: common_data.apply(subelem)
+ containerobj.append(subelem)
+ subelem.index = read_impl_count[0]
+ read_impl_count[0] = read_impl_count[0] + 1
+
+ if common_data:
+ common_data.apply(containerobj)
+ containerobj._tempvar_defs = common_data.tempvar_defs + containerobj._tempvar_defs
+ return containerobj
+
+ @classmethod
+ def read_implementation(cls, xml_data):
+ """
+ Read a container implementation from the given xmlroot element.
+ """
+ root = utils.etree.fromstring(xml_data)
+ return cls.read_impl("", None,root)
+
+ @classmethod
+ def get_condition(cls, root):
+ if root.get('condition'):
+ left = root.get('condition')
+ right = root.get('value', 'true')
+ return rules.SimpleCondition(left, right)
+ else:
+ return None
+
+class ImplSet(sets.Set):
+ """
+ Implementation set class that can hold a set of ImplBase instances.
+ """
+
+ """
+ The plugin phases is a list of possible phases in which the plugins are executed.
+ Each plugin instance can tell in which phase it needs to be executed.
+ """
+ INVOCATION_PHASES = ['pre','normal','post']
+
+ def __init__(self,implementations=None, generation_context=None):
+ super(ImplSet,self).__init__(implementations)
+ self.output = 'output'
+ if generation_context:
+ self.generation_context = generation_context
+ else:
+ self.generation_context = GenerationContext()
+
+ def invocation_phases(self):
+ """
+ @return: A list of possible invocation phases
+ """
+ return self.INVOCATION_PHASES
+
+ def list_output_files(self):
+ """
+ List the output file names from this container.
+ """
+ filelist = []
+ for impl in self:
+ files = impl.list_output_files()
+ filelist.extend(files)
+ return utils.distinct_array(filelist)
+
+ def generate(self, context=None):
+ """
+ Generate all implementations.
+ @return:
+ """
+ #for impl in self.impls:
+ # impl.generation_context = self.generation_context
+ if not context:
+ context = self.generation_context
+ self.execute(self, 'generate', context)
+
+ def post_generate(self, context=None):
+ """
+ @attention: This is a temporary method used for implementing cenrep_rfs.txt generation.
+ """
+ if not context:
+ context = self.generation_context
+ self.execute(self, 'post_generate', context)
+
+ def execute(self, implementations, methodname, *args):
+ """
+ Internal function for executing a function to a list of implementations.
+
+ Mutual execution order (for separate implementation instances defined in
+ the same implementation file) is the order the implementations are
+ specified in the file.
+
+ @param implementations:
+ @param methodname: the name of the function to execute
+ """
+ # Sort by (file_name, index_in_file) to ensure the correct execution order
+ impls = sorted(implementations, key=lambda impl: (impl.ref, impl.index))
+ for impl in impls:
+ try:
+ impl.set_output_root(self.output)
+ if hasattr(impl, methodname):
+ _member = getattr(impl, methodname)
+ _member(*args)
+ else:
+ logging.getLogger('cone').error('Impl %r has no method %s' % (impl, methodname))
+ except Exception, e:
+ utils.log_exception(logging.getLogger('cone'), 'Impl %r raised an exception: %s' % (impl, repr(e)))
+
+
+ def add_implementation(self,impl):
+ """
+ Add a ImplBase object to this ImplBaseContainer.
+ """
+ self.add(impl)
+
+ def remove_implementation(self,ref):
+ """
+ Remove implementation object by its ref (name of the implml resource).
+ """
+ impls_to_remove = []
+ for impl in self:
+ if impl.ref == ref:
+ impls_to_remove.append(impl)
+
+ for impl in impls_to_remove:
+ self.remove(impl)
+
+ def list_implementation(self):
+ """
+ List all implementation in this container.
+ @return: an array of resource references.
+ """
+ implrefs = []
+ for impl in self:
+ if impl.ref not in implrefs:
+ implrefs.append(impl.ref)
+ return implrefs
+
+ def get_implementations_by_file(self, ref):
+ """
+ Return a list of implementations read from the given file.
+ """
+ return filter(lambda impl: impl.ref == ref, self)
+
+ def filter_implementations(self,**kwargs):
+ """
+ Find any implementation with certain parameters.
+ All arguments are given as dict, so they must be given with name. E.g. copy(phase='normal')
+ @param phase: name of the phase
+ @param refs: A list of refs that are filtered with function has_refs
+ @param tags: A dictionary of tags that are filtered with function has_tags
+ @return: a new ImplSet object with the filtered items.
+ """
+ impls = []
+ """ Create a list of filter functions for each argument """
+ filters=[]
+ filters.append(lambda x: x != None)
+ if kwargs.get('phase', None) != None:
+ filters.append(lambda x: kwargs.get('phase') in x.invocation_phase())
+ if kwargs.get('refs',None) != None:
+ # Changed has_ref usage to allow not supporting refs (meaning that non supported wont be filtered with refs)
+ filters.append(lambda x: x.has_ref(kwargs.get('refs')) == True or x.has_ref(kwargs.get('refs')) == None)
+ if kwargs.get('tags', None) != None:
+ filters.append(lambda x: x.has_tag(kwargs.get('tags'),kwargs.get('policy')))
+
+ """ Go through the implementations and add all to resultset that pass all filters """
+ for impl in self:
+ pass_filters = True
+ for filter in filters:
+ if not filter(impl):
+ pass_filters = False
+ break
+ if pass_filters:
+ impls.append(impl)
+ return ImplSet(impls)
+
+ def flat_compare(self, other):
+ """
+ Perform a flat comparison between this implementation container and another one.
+ @return: @return: A FlatComparisonResult object.
+ """
+ # Collect dictionaries of all comparable implementation instances
+ # ---------------------------------------------------------------
+ source_impls_by_class, duplicates_in_source = self._get_flat_comparison_impl_by_class_dicts('source')
+ target_impls_by_class, duplicates_in_target = other._get_flat_comparison_impl_by_class_dicts('target')
+
+ # Collect a list containing all implementation classes
+ # ----------------------------------------------------
+ all_impl_classes = []
+ for impl_class in source_impls_by_class.iterkeys():
+ if impl_class not in all_impl_classes:
+ all_impl_classes.append(impl_class)
+ for impl_class in target_impls_by_class.iterkeys():
+ if impl_class not in all_impl_classes:
+ all_impl_classes.append(impl_class)
+
+ # Perform comparison for all classes
+ # ----------------------------------
+ result = FlatComparisonResult()
+ for impl_class in all_impl_classes:
+ src = source_impls_by_class.get(impl_class, {})
+ tgt = target_impls_by_class.get(impl_class, {})
+ temp_result = self._get_flat_comparison_result(impl_class, src, tgt)
+ result.extend(temp_result)
+
+ # Add duplicates into the comparison result
+ # -----------------------------------------
+ def get_or_add_dup_entry(impl_type_id, impl_id):
+ for e in result.duplicate:
+ if e.impl_type == impl_type_id and e.id == impl_id:
+ return e
+ e = DuplicateImplementationEntry(impl_type=impl_type_id, id=impl_id)
+ result.duplicate.append(e)
+ return e
+
+ for impl_class, impl_type_id, impl_id, file in duplicates_in_source:
+ entry = get_or_add_dup_entry(impl_type_id, impl_id)
+ entry.files_in_source.append(file)
+ for impl_class, impl_type_id, impl_id, file in duplicates_in_target:
+ entry = get_or_add_dup_entry(impl_type_id, impl_id)
+ entry.files_in_target.append(file)
+
+ # Sort the files so that the output is easier to compare in unit tests
+ for e in result.duplicate:
+ e.files_in_source.sort()
+ e.files_in_target.sort()
+
+ return result
+
+ def _get_flat_comparison_impl_by_class_dicts(self, name):
+ result = {}
+ duplicates = [] # List of (impl_class, impl_type_id, impl_id, file) tuples
+ for impl in self:
+ # See if the implementation is flat comparable
+ try:
+ impl_id = impl.get_flat_comparison_id()
+ except exceptions.NotSupportedException:
+ continue
+
+ # Get the dictionary where implementations of this type are collected
+ impl_class = type(impl)
+ if impl_class not in result:
+ result[impl_class] = {}
+ impls_dict = result[impl_class]
+
+ # Add to the dictionary
+ if impl_id not in impls_dict:
+ impls_dict[impl_id] = impl
+ else:
+ logging.getLogger('cone').warning("Multiple '%s' implementations with ID %r in %s" % (impl.IMPL_TYPE_ID, impl_id, name))
+ duplicates.append((impl_class, impl.IMPL_TYPE_ID, impl_id, impl.ref))
+
+ # Handle duplicates (add new duplicate entries and
+ # remove from the dictionaries)
+ new_duplicates = []
+ for impl_class, impl_type_id, impl_id, _ in duplicates:
+ # Get the corresponding dictionary
+ if impl_class not in result: continue
+ impls_dict = result[impl_class]
+ if impl_id not in impls_dict: continue
+ impl = impls_dict[impl_id]
+
+ # Add a new entry
+ new_duplicates.append((impl_class, impl.IMPL_TYPE_ID, impl_id, impl.ref))
+
+ # Remove from the dictionary
+ del impls_dict[impl_id]
+ duplicates.extend(new_duplicates)
+
+ return result, duplicates
+
+ def _get_flat_comparison_result(self, impl_class, source_impls_dict, target_impls_dict):
+ result = FlatComparisonResult()
+ impl_type_id = impl_class.get_flat_comparison_impl_type_id()
+
+ for impl_id, impl in target_impls_dict.iteritems():
+ if impl_id not in source_impls_dict:
+ result.only_in_target.append(FlatComparisonResultEntry(
+ file = impl.ref,
+ impl_type = impl_type_id,
+ id = impl_id,
+ data = impl.get_flat_comparison_extra_data()))
+
+
+ def fill_in_fields(entries, field_values):
+ for entry in entries:
+ for varname, value in field_values.iteritems():
+ setattr(entry, varname, value)
+
+ for impl_id, src_impl in source_impls_dict.iteritems():
+ if impl_id not in target_impls_dict:
+ result.only_in_source.append(FlatComparisonResultEntry(
+ file = src_impl.ref,
+ impl_type = impl_type_id,
+ id = impl_id,
+ data = src_impl.get_flat_comparison_extra_data()))
+ else:
+ tgt_impl = target_impls_dict[impl_id]
+
+ temp_result = src_impl.flat_compare(tgt_impl)
+ field_values = {'file' : tgt_impl.ref,
+ 'impl_type' : impl_type_id,
+ 'id' : impl_id}
+ fill_in_fields(temp_result.only_in_source, field_values)
+ fill_in_fields(temp_result.only_in_target, field_values)
+ fill_in_fields(temp_result.modified, field_values)
+ result.extend(temp_result)
+
+ return result
+
+ def create_temp_features(self, configuration):
+ """
+ Create all temporary features for the implementations in this container.
+
+ @param configuration: The configuration where the temporary features are
+ to be created.
+ @return: A list containing the references of all created temporary features.
+
+ @raise exceptions.AlreadyExists: Any of the temporary features already exists
+ in the configuration, or there are duplicate temporary features defined.
+ """
+ # ----------------------------------------------------
+ # Collect a list of all temporary variable definitions
+ # and check for duplicates and already existing
+ # features at the same time
+ # ----------------------------------------------------
+ tempvar_defs = []
+ files_by_refs = {}
+ dview = configuration.get_default_view()
+
+ for impl in self:
+ for fea_def in impl.get_temp_variable_definitions():
+ # Check if already exists
+ try:
+ dview.get_feature(fea_def.ref)
+ raise exceptions.AlreadyExists(
+ "Temporary variable '%s' defined in file '%s' already exists in the configuration!" \
+ % (fea_def.ref, impl.ref))
+ except exceptions.NotFound:
+ pass
+
+ # Add to temporary dictionary for duplicate checking
+ if fea_def.ref not in files_by_refs:
+ files_by_refs[fea_def.ref] = []
+ files_by_refs[fea_def.ref].append(impl.ref)
+
+ # Add to the list of all temp feature definitions
+ tempvar_defs.append(fea_def)
+
+ # Check for duplicates
+ for ref, file_list in files_by_refs.iteritems():
+ if len(file_list) > 1:
+ raise exceptions.AlreadyExists(
+ "Duplicate temporary variable! '%s' defined in the following files: %r" \
+ % (ref, file_list))
+ del files_by_refs
+
+
+ # ------------------------------
+ # Create the temporary variables
+ # ------------------------------
+ refs = []
+ if tempvar_defs:
+ logging.getLogger('cone').debug('Creating %d temporary variable(s)' % len(tempvar_defs))
+ autoconfig = get_autoconfig(configuration)
+ for fea_def in tempvar_defs:
+ fea_def.create_feature(autoconfig)
+ refs.append(fea_def.ref)
+
+ # The default view needs to be recreated, or the created
+ # features will not be visible there
+ configuration.recreate_default_view()
+ return refs
+
+ def get_relation_container(self):
+ """
+ Return a relation container containing all rules from this set
+ of implementation instances.
+ """
+ container = RelationContainer([], '')
+ for impl in self:
+ c = impl.get_relation_container()
+ if isinstance(c, RelationContainer):
+ container.entries.append(c)
+ return container
+
+ def get_all_implementations(self):
+ """
+ Return a flattened list of all implementation instances in this set.
+
+ The returned list contains only actual implementation instances, not
+ ImplContainer objects.
+ """
+ # Get a list of implementation objects sorted by file name
+ impl_list = list(self)
+ impl_list.sort(key=lambda impl: impl.ref)
+
+ result = []
+ for impl in impl_list:
+ result += impl.get_all_implementations()
+ return result
+
+
+class RelationExecutionResult(object):
+ """
+ Class representing a result from relation execution.
+ """
+ def __init__(self, input_refs, affected_refs, source=None, index=None):
+ """
+ @param input_refs: Input references, i.e. the references on the left side of
+ the relation.
+ @param affected_refs: Affected references, i.e. the references of the setting
+ that have been assigned something as a result of the relation execution.
+ @param source: The source of the relation. Can be e.g. the path to a RuleML file.
+ @param index: The index (number) of the relation in the source. This could be
+ e.g. 1 to denote the first rule in a RuleML file.
+ """
+ self.input_refs = input_refs
+ self.affected_refs = affected_refs
+ self.source = source
+ self.index = index
+
+ def __repr__(self):
+ return "RelationExecutionResult(input_refs=%r, affected_refs=%r, source=%r, index=%r)" \
+ % (sorted(self.input_refs), sorted(self.affected_refs), self.source, self.index)
+
+ def __eq__(self, other):
+ if type(self) is not type(other):
+ return False
+ return sorted(self.input_refs) == sorted(other.input_refs) \
+ and sorted(self.affected_refs) == sorted(other.affected_refs) \
+ and self.source == other.source \
+ and self.index == other.index
+
+ def __ne__(self, other):
+ return not (self == other)
+
+class RelationContainer(object):
+ """
+ A relation container that may contain relations or other
+ RelationContainer objects.
+ """
+ def __init__(self, entries=[], source=None):
+ """
+ @param entries: The relations or relation containers to be added.
+ @param source: The source of the relations in this container. Can be
+ e.g. the path to a RuleML file.
+ """
+ self.entries = entries
+ self.source = source
+
+ def execute(self):
+ """
+ Execute all relations inside the container, logging any exceptions thrown
+ during the execution.
+ @return: A list of RelationExecutionResult objects.
+ """
+ results = []
+ for i, entry in enumerate(self.entries):
+ if isinstance(entry, rules.RelationBase):
+ result = self._execute_relation_and_log_error(entry, self.source, i + 1)
+ if isinstance(RelationExecutionResult):
+ results.append(result)
+ elif isinstance(entry, RelationContainer):
+ results.extend(self._execute_container_and_log_error(entry))
+ else:
+ logging.getLogger('cone').warning("Invalid RelationContainer entry: type=%s, obj=%r" % (type(entry), entry))
+ return results
+
+ def _execute_relation_and_log_error(self, relation, source, index):
+ """
+ Execute a relation, logging any exceptions that may be thrown.
+ @param relation: The relation to execute.
+ @param source: The source of the rule.
+ @param index: The index of the rule, can be None if the index is not known.
+ @return: The return value from the relation execution, or None if an error occurred.
+ """
+ try:
+ return relation.execute()
+ except Exception, e:
+ log = logging.getLogger('cone')
+ if index is not None:
+ utils.log_exception(log, "Error executing rule no. %s in '%s'" % (index, source))
+ else:
+ utils.log_exception(log, "Error executing a rule in '%s'" % relation_or_container.source)
+ return None
+
+ def _execute_container_and_log_error(self, container):
+ """
+ Execute a relation container, logging any exceptions that may be thrown.
+ @param relation: The relation container to execute.
+ @return: The results from the relation execution, or an empty list if an error occurred.
+ """
+ try:
+ return container.execute()
+ except Exception, e:
+ log = logging.getLogger('cone')
+ utils.log_exception(log, "Error executing rules in '%s'" % container.source)
+ return []
+
+ def get_relation_count(self):
+ """
+ Return the number of relations in this container.
+ """
+ count = 0
+ for entry in self.entries:
+ if isinstance(entry, RelationContainer):
+ count += entry.get_relation_count()
+ else:
+ count += 1
+ return count
+
+
+class ImplFactory(api.FactoryBase):
+
+ __registered_reader_classes = None
+ __registered_reader_classes_override = None
+ __common_reader_classes = [ImplContainerReader]
+
+ @classmethod
+ def get_reader_classes(cls):
+ """
+ return a list of reader classes
+ """
+ reader_classes = cls.__common_reader_classes[:]
+ # If the reader class list is overridden, return that
+ if cls.__registered_reader_classes_override is not None:
+ reader_classes += cls.__registered_reader_classes_override
+ else:
+ # Load the classes if not loaded already
+ if cls.__registered_reader_classes is None:
+ cls.__registered_reader_classes = cls.__load_reader_classes()
+ reader_classes += cls.__registered_reader_classes
+
+ return reader_classes
+
+ @classmethod
+ def get_reader_dict(cls):
+ """
+ return a dictionary of reader classes, where key is the reader namespace
+ """
+ reader_dict = {}
+ for reader in cls.get_reader_classes():
+ reader_dict[reader.NAMESPACE] = reader
+ return reader_dict
+
+ @classmethod
+ def get_supported_file_extensions(cls):
+ """
+ return a dictionary of reader classes, where key is the reader namespace
+ """
+ file_extensions = []
+ for reader in cls.get_reader_classes():
+ for fe in reader.FILE_EXTENSIONS:
+ file_extensions.append(fe.lower())
+ return file_extensions
+
+ @classmethod
+ def set_reader_classes_override(cls, reader_classes):
+ """
+ Override the list of registered reader classes.
+
+ This method is provided for unit tests.
+ @param reader_classes: Reader class list to use as override. Pass None to
+ disable overriding.
+ """
+ cls.__registered_reader_classes_override = reader_classes
+
+ @classmethod
+ def force_reload_reader_classes(cls):
+ """
+ Force-reload all reader classes.
+ """
+ cls.__registered_reader_classes = cls.__load_reader_classes()
+
+ @classmethod
+ def __load_reader_classes(cls):
+ """
+ Load all registered ImplML reader classes from plug-ins.
+ """
+ log = logging.getLogger('cone')
+ log.setLevel(logging.DEBUG)
+ reader_classes = []
+ ENTRY_POINT = 'cone.plugins.implmlreaders'
+
+ import pkg_resources
+ working_set = pkg_resources.WorkingSet(sys.path)
+ for entry_point in working_set.iter_entry_points(ENTRY_POINT):
+ reader_class = entry_point.load()
+ if not inspect.isclass(reader_class):
+ log.warn("'%s' entry point '%s' is not a class (%r)" % (ENTRY_POINT, entry_point.name, reader_class))
+ elif not issubclass(reader_class, ReaderBase):
+ log.warn("'%s' entry point '%s' is not a sub-class of cone.plugin.ReaderBase (%r)" % (ENTRY_POINT, entry_point.name, reader_class))
+ else:
+ msg = "Reader class for XML namespace '%s' loaded from egg '%s' entry point '%s'" % (reader_class.NAMESPACE, ENTRY_POINT, entry_point.name)
+ log.debug(msg)
+ #print msg
+ reader_classes.append(reader_class)
+
+ return reader_classes
+
+ @classmethod
+ def is_supported_impl_file(cls, file_name):
+ """
+ Return whether the given file is a supported implementation file.
+ """
+ ext = os.path.splitext(file_name)[1]
+ if ext is not None:
+ return ext[1:].lower() in cls.get_supported_file_extensions()
+ else:
+ return False
+
+ @classmethod
+ def get_impls_from_file(cls, resource_ref, configuration):
+ """
+ Get a list of implementation instances from the given file (resource in a configuration).
+
+ @param resource_ref: Reference of the resource to read the impls from.
+ @param configuration: The configuration to use.
+ @return: List of implementation instances parsed and created from the file.
+
+ @raise NotSupportedException: The file contains an XML namespace that is
+ not registered as an ImplML namespace.
+ """
+ try:
+ impls = []
+ reader_dict = cls.get_reader_dict()
+ root = ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
+ ns = utils.xml.split_tag_namespace(root.tag)[0]
+ if ns not in reader_dict.keys():
+ logging.getLogger('cone').error("Error: no reader for namespace '%s' in %s" % (ns, resource_ref))
+ return []
+ rc = reader_dict[ns]
+ # return the single implementation as a list to maintain
+ # backwards compability
+ impl = rc.read_impl(resource_ref, configuration, root)
+ impl.index = 0
+ return [impl]
+ except exceptions.ParseError, e:
+ # Invalid XML data in the file
+ logging.getLogger('cone').error("Implementation %s reading failed with error: %s" % (resource_ref,e))
+ return []
+
+def get_impl_set(configuration,filter='.*'):
+ """
+ return a ImplSet object that contains all implementation objects related to the
+ given configuration
+ """
+ impls = configuration.get_layer().list_implml()
+ impls = pre_filter_impls(impls)
+ # filter the resources with a given filter
+ impls = utils.resourceref.filter_resources(impls,filter)
+ impl_container = create_impl_set(impls,configuration)
+ return impl_container
+
+def filtered_impl_set(configuration,pathfilters=None, reffilters=None):
+ """
+ return a ImplSet object that contains all implementation objects related to the
+ given configuration
+ """
+ if pathfilters: logging.getLogger('cone').info('Filtering impls with %s' % pathfilters)
+ impls = configuration.get_layer().list_implml()
+ impls = pre_filter_impls(impls)
+ # filter the resources with a given filter
+ if pathfilters:
+ newimpls = []
+ for filter in pathfilters:
+ newimpls += utils.resourceref.filter_resources(impls,filter)
+ impls = utils.distinct_array(newimpls)
+ impl_container = create_impl_set(impls,configuration,reffilters)
+ return impl_container
+
+def create_impl_set(impl_filename_list, configuration,reffilters=None):
+ impl_filename_list = pre_filter_impls(impl_filename_list)
+ if reffilters: logging.getLogger('cone').info('Filtering with refs %s' % reffilters)
+ impl_container = ImplSet()
+ for impl in impl_filename_list:
+ try:
+ if configuration != None and ImplFactory.is_supported_impl_file(impl):
+ plugin_impls = ImplFactory.get_impls_from_file(impl, configuration)
+ for plugin_impl in plugin_impls:
+ if not reffilters or plugin_impl.has_ref(reffilters):
+ impl_container.add_implementation(plugin_impl)
+ except Exception, e:
+ utils.log_exception(logging.getLogger('cone'), "Creating impl '%s' failed. Exception: %s" % (impl,e))
+ continue
+ return impl_container
+
+def pre_filter_impls(impls):
+ """
+ Pre-filter implementation file refs so that files and directories
+ beginning with a dot (e.g. '.svn', '.scripts') are ignored.
+ """
+ filter = r'(/|^|\\)\..*(/|$|\\)'
+ return utils.resourceref.neg_filter_resources(impls, filter)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/rules.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/rules.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,767 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import operator as ops
+import logging
+import tokenize
+from token import ENDMARKER, NAME, ERRORTOKEN
+import StringIO
+
+from cone.public import container
+
+RELATIONS = {}
+
+def abstract():
+ import inspect
+ caller = inspect.getouterframes(inspect.currentframe())[1][3]
+ raise NotImplementedError(caller + ' needs to be implemented')
+
+def get_tokens(tokenstr):
+ result = []
+ tokens = []
+ tokenstr = tokenstr.replace('\r', '')
+ name_buffer = [] # Temp buffer for reading name tokens
+ last_epos = None
+ for toknum, tokval, spos, epos, _ in tokenize.generate_tokens(StringIO.StringIO(unicode(tokenstr)).readline):
+ #print "toknum: %r, tokval: %r, spos: %r, epos: %r" % (toknum, tokval, spos, epos)
+ val = tokval.strip('\r\n\t ')
+
+ if toknum == ENDMARKER and name_buffer:
+ tokens.append(''.join(name_buffer))
+
+ # Ignore whitespace (this ignores also the end marker,
+ # since its value is empty)
+ if val == '': continue
+
+ # Put NAME, and ERRORTOKEN tokens through the temp
+ # buffer
+ if toknum in (NAME, ERRORTOKEN):
+ # If this and the previous token in the temp buffer are not adjacent,
+ # they belong to separate tokens
+ if name_buffer and spos[1] != last_epos[1]:
+ tokens.append(''.join(name_buffer))
+ name_buffer = []
+
+ name_buffer.append(val)
+ last_epos = epos
+ # Other tokens can just go directly to the token list
+ else:
+ if name_buffer:
+ tokens.append(''.join(name_buffer))
+ name_buffer = []
+ tokens.append(val)
+
+ while len(tokens) > 0:
+ val = tokens.pop(0)
+ # Join the refs with dot in between them to make them dotted refs
+ if val == '.':
+ newval = ".".join([result.pop(),tokens.pop(0)])
+ result.append( newval )
+ else:
+ result.append( val )
+
+ return result
+
+class RelationException(Exception):
+ pass
+
+#### The containers are here ####
+
+
+class RelationBase(object):
+ """
+ RelationBase defines a base class for all named relations that can be applied between objects.
+ e.g. Relation depends, that can be applied in Rule
+ """
+ relation_name = "RelationBase"
+ def __init__(self, data, left, right):
+ self.description = ""
+ self.data = data or container.DataContainer()
+ self.left = left
+ self.right = right
+
+ def __str__(self):
+ """
+ @return: A string presentation of the relation object
+ """
+ return "%s %s %s" % (self.left,self.relation_name,self.right)
+
+ def get_name(self):
+ """
+ @return: The relation name.
+ """
+ return self.relation_name
+
+ def get_description(self):
+ """
+ @return: a possible description of the relation.
+ """
+ return self.description
+
+ def execute(self):
+ """
+ Execute the relation object.
+ """
+ pass
+
+
+class RelationContainer(RelationBase, list):
+ """
+ This class provides the RelationContainer interface for collecting
+ relation sets into one place which can be executed through the container.
+ """
+ def __init__(self, data=None):
+ super(RelationContainer, self).__init__(data, 'LContainer', 'RContainer')
+ self.value_list = list()
+
+ def append(self, value):
+ self.value_list.append(value)
+
+ def __iter__(self):
+ return self.value_list.__iter__()
+
+ def __len__(self):
+ return len(self.value_list)
+
+ def __or__(self, other):
+ """
+ This function adds two RelationContainers to each other and removes
+ duplicates from the result.
+ The modification is inplace and the returned value is called object.
+ """
+ self.value_list = set(self.value_list) | set(other.value_list)
+ return self
+
+ def __unicode__(self):
+ if self:
+ ret = ''
+ for value in self:
+ ret += unicode(value)
+ else:
+ ret = 'No relations'
+ return ret
+
+ def find_relations(self, refs): abstract()
+ def add_relation(self, relation): abstract()
+ def has_errors(self): abstract()
+
+class RelationContainerImpl(RelationContainer):
+ """ Base implementation for RelationContainer to use in ConE rules
+ """
+ def execute(self):
+ ret = True
+ i = 0
+ for relation in self:
+ i += 1
+ r = relation.execute()
+ ret = ret and r
+ return ret
+
+ def find_relations(self, refs):
+ relations = []
+ for ref in refs:
+ for relation in self:
+ if relation.has_ref(ref):
+ relations.append(relation)
+ return relations
+
+ def add_relation(self, relation):
+ self.append(relation)
+
+ def has_ref(self, refs):
+ for ref in refs:
+ for relation in self:
+ if relation.has_ref(ref):
+ return True
+ return False
+
+ def has_errors(self):
+ for relation in self:
+ if relation.has_errors():
+ return True
+ return False
+
+ def get_errors(self):
+ errors = []
+ for relation in self:
+ errors += relation.get_errors()
+ return errors
+
+#### The relations are here ####
+
+class BaseRelation(RelationBase):
+ """ BaseRelation implements the basic evaluation logic for relations
+ This class abstract and should be extended for concrete implementation of
+ relation type.
+
+ Subclasses need to set their own context in their constructor before this
+ class's constructor is called if custom context is needed. If context not
+ set then DefaultContext is used.
+ """
+ KEY = 'base_relation'
+
+ def __init__(self, data, left, right):
+ # Context needs to be overridden for special purposes
+ try:
+ self.__getattribute__('context')
+ except AttributeError:
+ self.context = DefaultContext(data)
+
+ left = self.expand_rule_elements(left)
+ right = self.expand_rule_elements(right)
+ super(BaseRelation, self).__init__(data, left, right)
+ self.interpreter = ASTInterpreter(context=self.context)
+
+ def execute(self):
+ """
+ @return Returns error dictionary
+
+ In the client code proper way to check if the rule applies:
+ info = relation.execute()
+ if not info.has_errors():
+ else: HANDLE ERRORS
+ """
+ # logger.debug("Interpreter context %s" % self.interpreter.context)
+ self.interpreter.create_ast('%s %s %s' % (self.left, self.KEY, self.right))
+ ret = self.interpreter.eval()
+ return ret
+
+ def get_keys(self):
+ """ Returns the references from this relation.
+ """
+ refs = ASTInterpreter.extract_refs(self.left)
+ refs += ASTInterpreter.extract_refs(self.right)
+ return refs
+
+ def has_ref(self, ref):
+ """ Returns if the 'ref' is included in this relation
+ """
+ return ref in self.get_keys()
+
+ def has_errors(self):
+ return bool(self.interpreter.errors)
+
+ def get_refs(self):
+ return (ASTInterpreter.extract_refs(self.left), ASTInterpreter.extract_refs(self.right))
+
+ def _eval_rside_value(self, value): abstract()
+ def _compare_value(self, value): abstract()
+
+ def extract_erroneus_features_with_values(self):
+ """
+ Extract references who have errors.
+
+ Returns dictionary { 'reference' : 'value' }
+ """
+ data_dict = {}
+ for ref in ASTInterpreter.extract_refs(self.right):
+ value = self.data.get_feature(ref)
+ if self._compare_value(value):
+ data_dict[ref] = value
+ elif value == None:
+ data_dict[ref] = None
+ return data_dict
+
+ def get_errors(self):
+ return self.interpreter.errors
+
+ def expand_rule_elements(self, rule):
+ """ Expans rule elements base on the reference.
+ Context is used for fetching the child elements for parent references
+ which uses asterisk identifier for selecting all child features:
+ 'parent_feature.*' -> 'child_fea_1 and child_fea_2'.
+ """
+ tokens = get_tokens(rule) # [token for token in rule.split()]
+
+ expanded_rule = ""
+ for token in tokens:
+ if token.endswith('.*'):
+ index = token.index('.*')
+ parent_ref = token[:index]
+ children = self.context.get_children_for_reference(parent_ref)
+ expanded_element = ' and '.join([child.reference for child in children])
+ if expanded_rule:
+ expanded_rule = '%s and %s' % (expanded_rule, expanded_element.rstrip())
+ else:
+ expanded_rule = expanded_element.rstrip()
+ elif token.lower() in OPERATORS:
+ expanded_rule += ' %s ' % token
+ else:
+ if expanded_rule:
+ expanded_rule += '%s'% token
+ else:
+ expanded_rule = token
+ return expanded_rule.strip()
+
+class RequireRelation(BaseRelation):
+ KEY = 'requires'
+RELATIONS[RequireRelation.KEY] = RequireRelation
+
+class ExcludesRelation(BaseRelation):
+ KEY = 'excludes'
+
+RELATIONS['excludes'] = ExcludesRelation
+
+################################
+# Abstract syntax tree builder #
+################################
+
+def nor(expression, a, b):
+ return not ops.or_(a, b)
+
+def nand(expression, a, b):
+ return not ops.and_(a, b)
+
+def truth_and(expression, a, b):
+ return ops.truth(a) and ops.truth(b)
+
+class DefaultContext(object):
+ """ DefaultContext implements ConE specific context for handling rules
+ """
+ def __init__(self, data):
+ self.data = data
+
+ def eval(self, ast, expression, value):
+ pass
+
+ def get_keys(self, refs):
+ return ASTInterpreter.extract_refs(refs)
+
+ def get_children_for_reference(self, reference):
+ # implement ConE specific children expansion
+ pass
+
+ def handle_terminal(self, expression):
+ try:
+ return int(expression)
+ except:
+ return expression
+
+PRECEDENCES = {
+ 'PREFIX_OPERATORS' : 10,
+ 'MULDIV_OPERATORS' : 8,
+ 'ADDSUB_OPERATORS' : 7,
+ 'SHIFT_OPERATORS' : 6,
+ 'BITWISE_OPERATORS' : 5,
+ 'COMPARISON_OPERATORS' : 4,
+ 'SET_OPERATORS' : 3,
+ 'BOOLEAN_OPERATORS' : 2,
+ 'RELATION_OPERATORS' : 1,
+ 'NOT_DEFINED' : 0
+}
+
+class Expression(object):
+ PRECEDENCE = PRECEDENCES['NOT_DEFINED']
+ KEY = 'base_expression'
+
+ def __init__(self, ast):
+ self.ast = ast
+ self.value = None
+
+ def get_title(self):
+ return self.KEY
+
+ def eval(self, context): pass
+
+class OneParamExpression(Expression):
+ PARAM_COUNT = 1
+ def __init__(self, ast, expression):
+ super(OneParamExpression, self).__init__(ast)
+ self.expression = expression
+
+ def __unicode__(self):
+ return u'%s %s' % (self.KEY, self.expression)
+
+ def eval(self, context):
+ self.value = self.OP(self.expression.eval(context))
+ context.eval(self.ast, self, self.value)
+ return self.value
+
+class TwoOperatorExpression(Expression):
+ PARAM_COUNT = 2
+ OP = None
+ EVAL_AS_BOOLS = True
+
+ def __init__(self, ast, left, right):
+ super(TwoOperatorExpression, self).__init__(ast)
+ self.left = left
+ self.right = right
+
+ def __unicode__(self):
+ return u'%s %s %s' % (self.left, self.KEY, self.right)
+
+ def eval(self, context):
+ self.value = self.OP(self.left.eval(context), self.right.eval(context))
+ context.eval(self.ast, self, self.value)
+ return self.value
+
+class TwoOperatorBooleanExpression(TwoOperatorExpression):
+ def eval(self, context):
+ self.value = self.OP(bool(self.left.eval(context)), bool(self.right.eval(context)))
+ context.eval(self.ast, self, self.value)
+ return self.value
+
+class TerminalExpression(Expression):
+ KEY = 'terminal'
+
+ def __init__(self, ast, expression):
+ super(TerminalExpression, self).__init__(ast)
+ self.expression = expression
+
+ def eval(self, context):
+ """ Use context to eval the value
+ Expression on TerminalExpression is feature reference or value
+ context should handle the reference conversion to correct value
+ """
+ self.value = context.handle_terminal(self.expression)
+ return self.value
+
+ def __unicode__(self):
+ return self.expression
+
+ def __repr__(self):
+ return self.expression
+
+class NegExpression(OneParamExpression):
+ PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
+ KEY= '-'
+ OP = ops.neg
+
+class AndExpression(TwoOperatorBooleanExpression):
+ PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+ KEY= 'and'
+ OP = truth_and
+
+class NandExpression(TwoOperatorBooleanExpression):
+ PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+ KEY = 'nand'
+ OP = nand
+
+class OrExpression(TwoOperatorBooleanExpression):
+ PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+ KEY = 'or'
+ OP = ops.or_
+
+class XorExpression(TwoOperatorBooleanExpression):
+ PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+ KEY = 'xor'
+ OP = ops.xor
+
+class NorExpression(TwoOperatorBooleanExpression):
+ PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+ KEY = 'nor'
+ OP = nor
+
+class EqualExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+ KEY = '=='
+ OP = ops.eq
+
+class NotEqualExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+ KEY = '!='
+ OP = ops.ne
+
+class LessThanExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+ KEY = '<'
+ OP = ops.lt
+
+class GreaterThanExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+ KEY = '>'
+ OP = ops.gt
+
+class LessThanEqualExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+ KEY = '<='
+ OP = ops.le
+
+class GreaterThanEqualExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+ KEY = '>='
+ OP = ops.ge
+
+
+def handle_require(expression, left, right):
+ if left and right:
+ return True
+ elif not left:
+ return True
+ return False
+
+class RequireExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['RELATION_OPERATORS']
+ KEY = 'requires'
+ OP = handle_require
+
+ def eval(self, context):
+ super(RequireExpression, self).eval(context)
+ if not self.value:
+ left_keys = []
+ for ref in self.ast.extract_refs(unicode(self.left)):
+ for key in context.get_keys(ref):
+ left_keys.append(key)
+
+ for key in left_keys:
+ self.ast.add_error(key, { 'error_string' : 'REQUIRES right side value is "False"',
+ 'left_key' : key,
+ 'rule' : self.ast.expression
+ })
+ return self.value
+
+def handle_exclude(expression, left, right):
+ if left and not right:
+ return True
+ elif not left:
+ return True
+ return False
+
+class ExcludeExpression(TwoOperatorExpression):
+ PRECEDENCE = PRECEDENCES['RELATION_OPERATORS']
+ KEY = 'excludes'
+ OP = handle_exclude
+
+ def eval(self, context):
+ super(ExcludeExpression, self).eval(context)
+ if not self.value:
+ left_keys = []
+ for ref in self.ast.extract_refs(unicode(self.left)):
+ for key in context.get_keys(ref):
+ left_keys.append(key)
+
+ for key in left_keys:
+ self.ast.add_error(key, { 'error_string' : 'EXCLUDE right side value is "True"',
+ 'left_key' : key,
+ 'rule' : self.ast.expression
+ })
+ return self.value
+
+
+class NotExpression(OneParamExpression):
+ PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
+ KEY = 'not'
+ OP = ops.not_
+
+class TruthExpression(OneParamExpression):
+ PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
+ KEY = 'truth'
+ OP = ops.truth
+
+LEFT_PARENTHESIS = '('
+RIGHT_PARENTHESIS = ')'
+class SimpleCondition(EqualExpression):
+ """
+ A simple condition object that can refer to a model object and evaluate if the value matches
+ """
+ def __init__(self, left, right):
+ lterm = TerminalExpression(None, left)
+ rterm = TerminalExpression(None, right)
+ EqualExpression.__init__(self, None, lterm, rterm)
+
+
+# in format KEY : OPERATOR CLASS
+OPERATORS = {
+ 'and' : AndExpression,
+ 'nand' : NandExpression,
+ 'or' : OrExpression,
+ 'xor' : XorExpression,
+ 'nor' : NorExpression,
+ 'not' : NotExpression,
+ 'truth' : TruthExpression,
+ '==' : EqualExpression,
+ '!=' : NotEqualExpression,
+ '<' : LessThanExpression,
+ '>' : GreaterThanExpression,
+ '<=' : LessThanEqualExpression,
+ '>=' : GreaterThanEqualExpression,
+ 'requires' : RequireExpression,
+ 'excludes' : ExcludeExpression,
+ '-' : NegExpression
+ }
+
+def add_operator(key, operator_class=None, baseclass=RequireExpression):
+ """
+ Add new operator key and operator class.
+ If operator class isn't provided the baseclass parameter is used as
+ operator base. The baseclass parameter is RequireExpression by default
+ which has success condition left_rule=True and right_rule=True
+
+ """
+ OPERATORS[key] = operator_class or create_new_class(key, baseclass)
+
+def create_new_class(key, baseclass):
+ ns = baseclass.__dict__.copy()
+ ns['KEY'] = key
+ key_pieces = key.split('_')
+ class_prefix = ''.join([key_piece.capitalize() for key_piece in key_pieces])
+ new_class = type(class_prefix + 'Expression', (baseclass,), ns)
+ return new_class
+
+class ParseException(Exception): pass
+
+class ASTInterpreter(object):
+ def __init__(self, infix_expression=None, context=None):
+ """ Takes infix expression as string """
+ self.context = context or DefaultContext(None)
+ # logger.debug("AST init context: %s" % self.context)
+ self._init_locals(infix_expression)
+ if infix_expression:
+ self.create_ast()
+
+ def _init_locals(self, infix_expression):
+ # The result value of full eval of the parse_tree
+ self.value = None
+ self.warnings = {}
+ self.errors = {}
+ self.postfix_array = []
+ self.parse_tree = []
+ self.expression = infix_expression
+
+ def __unicode__(self):
+ s = ''
+ for expr in self.parse_tree:
+ s += unicode(expr)
+ return s
+
+ def add_error(self, key, error_dict):
+ if self.errors.has_key(key):
+ self.errors[key].append(error_dict)
+ else:
+ self.errors[key] = [error_dict]
+
+ def create_ast(self, infix_expression=None):
+ if infix_expression:
+ self._init_locals(infix_expression)
+ self._infix_to_postfix()
+ self._create_parse_tree()
+ return self.parse_tree
+
+ def _infix_to_postfix(self):
+ """
+ Shunting yard algorithm used to convert infix presentation to postfix.
+ """
+ if not self.expression:
+ raise ParseException('Expression is None')
+ tokens = get_tokens(self.expression) # [token for token in self.expression.split()]
+ stack = []
+ # logger.debug('TOKENS: %s' % tokens)
+ for token in tokens:
+ # logger.debug('TOKEN: %s' % token)
+ if token.lower() in OPERATORS:
+ op_class = OPERATORS.get(token)
+ if stack:
+ while len(stack) != 0:
+ top = stack[-1]
+ if top in OPERATORS:
+ top_operator = OPERATORS.get(top)
+ if op_class.PRECEDENCE <= top_operator.PRECEDENCE:
+ self.postfix_array.append(stack.pop())
+ else:
+ # Break from loop if top operator precedence is less.
+ break
+ else:
+ # If top not operator break from loop
+ break
+ stack.append(token)
+ elif token == LEFT_PARENTHESIS:
+ # logger.debug('Left parenthesis')
+ stack.append(token)
+ elif token == RIGHT_PARENTHESIS:
+ # logger.debug('Right parenthesis')
+ left_par_found = False
+ stack_token = stack.pop()
+ while stack_token:
+ if stack_token != LEFT_PARENTHESIS:
+ self.postfix_array.append(stack_token)
+ else:
+ left_par_found = True
+ break
+ if stack:
+ stack_token = stack.pop()
+ else:
+ stack_token = None
+
+ if not left_par_found:
+ raise ParseException('Mismatched parenthesis "%s".' % LEFT_PARENTHESIS)
+ else:
+ # logger.debug('Adding value to output. %s' % repr((token)))
+ self.postfix_array.append((token))
+
+ # There should be only operators left in the stack
+ if stack:
+ # logger.debug('Operators in stack.')
+ operator = stack.pop()
+ while operator:
+ if operator != LEFT_PARENTHESIS:
+ self.postfix_array.append(operator)
+ else:
+ raise ParseException('Mismatched parenthesis "%s".' % LEFT_PARENTHESIS)
+ if stack:
+ operator = stack.pop()
+ else:
+ operator = None
+
+ # logger.debug('Infix to postfix conversion: %s' % self.postfix_array)
+ return self.postfix_array
+
+ def _create_parse_tree(self):
+ self.parse_tree = []
+ for token in self.postfix_array:
+ if token in OPERATORS:
+ # logger.debug('OP: %s' % (token))
+ expression_class = OPERATORS[token]
+ params = []
+ for i in range(expression_class.PARAM_COUNT):
+ try:
+ params.append(self.parse_tree.pop())
+ except IndexError, e:
+ raise ParseException('Syntax error: "%s"' % self.expression)
+ params.reverse()
+ expression = expression_class(self, *params)
+
+ # logger.debug('The operation: %s' % expression)
+ self.parse_tree.append(expression)
+ else:
+ expression = TerminalExpression(self, token)
+ self.parse_tree.append(expression)
+
+ #logger.debug('THE STACK: %s' % self.parse_tree)
+ #for s in self.parse_tree:
+ # logger.debug('Stack e: %s' % str(s))
+
+ return self.parse_tree
+
+ def eval(self):
+ """ Evals the AST
+ If empty expression is given, None is returned
+ """
+ for expression in self.parse_tree:
+ self.value = expression.eval(self.context)
+ return self.value
+
+ @staticmethod
+ def extract_refs(expression):
+ tokens = get_tokens(expression)
+ refs = []
+ for token in tokens:
+ if not token.lower() in OPERATORS and token != LEFT_PARENTHESIS and token != RIGHT_PARENTHESIS:
+ refs.append(token.strip('%s%s' % (LEFT_PARENTHESIS, RIGHT_PARENTHESIS)))
+ return refs
+
+##################################################################
+# Create and configure the main level logger
+logger = logging.getLogger('cone')
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/settings.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/settings.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,92 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import os
+import logging
+import ConfigParser
+
+DEFAULT_SECTION = 'DEFAULT'
+class ConeSettings(object):
+ def __init__(self, parser, section=DEFAULT_SECTION):
+ self.parser = parser
+ self.section = section
+
+ def get(self, property, default=None, vars=None):
+ """
+ Try to get a single property from the ConeSettings section. The method support the
+ ConfigParser interpolation of variables and deliver extra variables via the vars param.
+
+ 1. Try to get the property from configured section.
+ 2. If section is not found try to get it from DEFAULT section.
+ 3. Still if property is not found return the default values
+ @param property: the name of the setting property get
+ @param default: the default value to return if the property is not found from settings
+ @param vars: a dictionary of variables that are given to the ConfigParser get
+ for interpolation. e.g. {'output':'testing'}.
+
+ """
+ try:
+ return self.parser.get(self.section, property, False, vars)
+ # if the section is not found try to use default
+ except ConfigParser.NoSectionError:
+ try:
+ return self.parser.get(DEFAULT_SECTION, property, False, vars)
+ except ConfigParser.NoOptionError:
+ if default != None:
+ return self.parser._interpolate(DEFAULT_SECTION,property,default,vars)
+ else:
+ return default
+ # if the option is not found return the default value
+ except ConfigParser.NoOptionError:
+ if default != None:
+ return self.parser._interpolate(DEFAULT_SECTION,property,default,vars)
+ else:
+ return default
+ #return default
+
+
+class SettingsFactory(object):
+ configsettings = None
+ configpath = ''
+ defaultconfig = 'cone_defaults.cfg'
+
+ @classmethod
+ def get_defaultconfig_path(cls):
+ return os.path.join(cls.configpath,cls.defaultconfig)
+
+ @classmethod
+ def cone_parser(cls):
+ """
+ Get a singleton instance of ConfigParser.
+ """
+ if not cls.configsettings:
+ cls.configsettings = ConfigParser.ConfigParser()
+
+ try:
+ cls.configsettings.readfp(open(cls.get_defaultconfig_path()))
+ except IOError:
+ logging.getLogger('cone').warning("Could not read default configuration file %s" % cls.get_defaultconfig_path())
+ return cls.configsettings
+
+ @classmethod
+ def clear(cls):
+ """
+ Clear everything back to default so that the next time the settings are re-parsed.
+
+ This method is provided for unit testing purposes.
+ """
+ cls.configsettings = None
+ cls.configpath = ''
+ cls.defaultconfig = 'cone_defaults.cfg'
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/Import.pk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/Import.pk Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,110 @@
+ccopy_reg
+_reconstructor
+p0
+(ccone.storage.stringstorage
+StringStorage
+p1
+c__builtin__
+object
+p2
+Ntp3
+Rp4
+(dp5
+S'_order'
+p6
+(lp7
+S'test1'
+p8
+aS'test2'
+p9
+aS'test3'
+p10
+asS'container'
+p11
+I01
+sS'_children'
+p12
+(dp13
+g8
+g0
+(ccone.storage.stringstorage
+_StringStorageObject
+p14
+g2
+Ntp15
+Rp16
+(dp17
+S'_parent'
+p18
+g4
+sg6
+(lp19
+sg12
+(dp20
+sS'path'
+p21
+S'test1.txt'
+p22
+sS'data'
+p23
+S'Testing reading.\n'
+p24
+sS'_name'
+p25
+g8
+sbsg10
+g0
+(g14
+g2
+Ntp26
+Rp27
+(dp28
+g18
+g4
+sg6
+(lp29
+sg12
+(dp30
+sg21
+S'test3.txt'
+p31
+sg23
+g24
+sg25
+g10
+sbsg9
+g0
+(g14
+g2
+Ntp32
+Rp33
+(dp34
+g18
+g4
+sg6
+(lp35
+sg12
+(dp36
+sg21
+S'test2.txt'
+p37
+sg23
+g24
+sg25
+g9
+sbssS'curpath'
+p38
+S''
+p39
+sS'rootpath'
+p40
+S'temp/unload.pk'
+p41
+sg25
+S'C:\\DocumentsandSettings\\teerytko\\workspace\\cone_trunk\\source\\cone\\public\\tests\\Import_pk'
+p42
+sg18
+NsS'ref'
+p43
+g42
+sb.
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+if SOURCE_ROOT not in sys.path:
+ sys.path.append(SOURCE_ROOT)
+
+# Find all unittest_*.py files in this folder
+import re
+__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
+# Strip .py endings
+__all__ = map(lambda name: name[:-3], __all__)
+
+def collect_suite():
+ sys.path.insert(0, ROOT_PATH)
+ try:
+ suite = unittest.TestSuite()
+ for test_module in __all__:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+ finally:
+ del sys.path[0]
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/test_defaults.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/test_defaults.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+
+[DEFAULT]
+output_root=output
+output_subdir=
+plugin_output=
+output=%(output_root)s/%(output_subdir)s/%(plugin_output)s
+
+plugin_targets = 'rofs2','rofs3'
+
+generate_targets = 'rofs3'
+generate_layers = -1
+generate_impls =
+
+[CRML]
+plugin_output=private/1234576
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_base.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_base.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public import api,exceptions,utils, container
+
+class TestBase(unittest.TestCase):
+ # @test
+ def test_create_base(self):
+ base = api.Base("foo")
+ self.assertTrue(base)
+
+ def test_get_namespace(self):
+ base= api.Base("foo")
+ self.assertTrue(base)
+ self.assertEquals(base.namespace,"")
+
+ def test_properties(self):
+ base= api.Base("foo")
+ self.assertTrue(base)
+ self.assertEquals(base.ref,"foo")
+ self.assertEquals(base.fqr,"foo")
+ self.assertEquals(base.get_fullref(),"foo")
+ self.assertEquals(base.get_fullfqr(),"foo")
+
+ def test_create_hiearchy(self):
+ base= api.Base("foo")
+ base._add(api.Base("bar"))
+ self.assertTrue(base)
+ self.assertEquals(base.bar.find_parent(type=api.Base),base)
+ self.assertEquals(base.bar.namespace, 'foo')
+ self.assertEquals(base.bar.fqr, 'foo.bar')
+ self.assertEquals(base.bar.get_fullfqr(), 'foo.bar')
+
+ def test_create_hiearchy_with_container(self):
+ cont= api.Base("", container=True)
+ base= api.Base("foo")
+ base._add(api.Base("bar1"))
+ base._add(api.Base("bar2"))
+ base.bar2._add(api.Base("bar21"))
+ cont._add(base)
+ self.assertTrue(base)
+ self.assertEquals(cont.foo.bar2.bar21.find_parent(container=True), cont)
+ self.assertEquals(cont.foo.bar1.find_parent(type=api.Base),base)
+ self.assertEquals(cont.foo.bar1.namespace, 'foo')
+ self.assertEquals(cont.foo.bar2.bar21.namespace, 'foo.bar2')
+ self.assertEquals(cont.foo.bar2.bar21.fqr, 'foo.bar2.bar21')
+
+ def test_create_hiearchy_with_container_and_hidden_elem(self):
+ cont= api.Base("", container=True)
+ base= api.Base("foo")
+ base._add(api.Base("bar1"))
+ base._add(api.Base("_bar2"))
+ base._bar2._add(api.Base("bar21"))
+ cont._add(base)
+ self.assertTrue(base)
+ self.assertEquals(cont.foo._bar2.bar21.find_parent(container=True), cont)
+ self.assertEquals(cont.foo.bar1.find_parent(type=api.Base),base)
+ self.assertEquals(cont.foo._bar2.bar21.get_fullnamespace(), 'foo._bar2')
+ self.assertEquals(cont.foo._bar2.bar21.get_fullfqr(), 'foo._bar2.bar21')
+ self.assertEquals(cont.foo.bar1.namespace, 'foo')
+ self.assertEquals(cont.foo._bar2.bar21.namespace, 'foo')
+ self.assertEquals(cont.foo._bar2.bar21.fqr, 'foo.bar21')
+
+ def test_create_hiearchy_with_append(self):
+ cont= api.Base("", container=True)
+ base= api.Base("foo")
+ base._add(api.Base("bar1"),container.APPEND)
+ base._add(api.Base("bar1"),container.APPEND)
+ base.bar1[0]._add(api.Base("bar21"))
+ cont._add(base)
+ self.assertTrue(base)
+ self.assertEquals(cont.foo.bar1[1].get_fullnamespace(),'foo')
+ self.assertEquals(cont.foo.bar1[0].get_fullref(),'bar1[0]')
+ self.assertEquals(cont.foo.bar1[1].get_fullref(),'bar1[1]')
+ self.assertEquals(cont.foo.bar1[0].get_fullfqr(), 'foo.bar1[0]')
+ self.assertEquals(cont.foo.bar1[1].get_fullfqr(), 'foo.bar1[1]')
+ self.assertEquals(cont.foo.bar1[0].bar21.get_fullnamespace(), 'foo.bar1[0]')
+ self.assertEquals(cont.foo.bar1[0].bar21.get_fullfqr(), 'foo.bar1[0].bar21')
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_configuration.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_configuration.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,852 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public import api,exceptions,utils
+from cone.storage import persistentdictionary
+from cone.confml import persistentconfml
+
+class TestConfiguration(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ # @test
+ def test_create_configuration(self):
+ conf = api.Configuration("testmee.confml")
+ self.assertTrue(conf)
+
+ def test_get_root_configuration(self):
+ conf = api.Configuration("testmee.confml")
+ self.assertEquals(conf.get_root_configuration(),conf)
+ conf.add_configuration(api.Configuration("foo/foo.confml"))
+ conf.add_configuration(api.Configuration("fii/fii.confml"))
+ conf.fii__fii_confml.add_configuration(api.Configuration("fii/foo.confml"))
+ self.assertEquals(conf.fii__fii_confml.get_root_configuration(),conf)
+ self.assertEquals(conf.foo__foo_confml.get_root_configuration(),conf)
+ self.assertEquals(conf.fii__fii_confml.fii__foo_confml.get_root_configuration(),conf)
+
+ def test_get_last_configuration(self):
+ conf = api.Configuration("testmee.confml")
+ conf.add_configuration(api.Configuration("foo/foo.confml"))
+ conf.add_configuration(api.Configuration("fii/fii.confml"))
+ conf.add_configuration(api.Configuration("hii/hii.confml"))
+ conf.fii__fii_confml.add_configuration(api.Configuration("fii/foo.confml"))
+ self.assertEquals(conf.list_configurations(), ["foo/foo.confml","fii/fii.confml","hii/hii.confml"])
+
+ self.assertEquals(conf.get_configuration_by_index(-1).get_path(), "hii/hii.confml")
+ self.assertEquals(conf.get_configuration_by_index(0).get_path(), "foo/foo.confml")
+ self.assertEquals(conf.get_configuration_by_index(1).get_path(), "fii/fii.confml")
+ self.assertEquals(conf.get_configuration_by_index(2).get_path(), "hii/hii.confml")
+
+ def compareconfiguration(self, conf1,conf2):
+ self.assertEquals(conf1.path,conf2.path)
+ self.assertEquals(conf1.name,conf2.name)
+ self.assertEquals(conf1.ref,conf2.ref)
+ self.assertEquals(conf1.namespace,conf2.namespace)
+
+ def test_clone_single_configuration(self):
+ conf1 = api.Configuration("testmee.confml")
+ conf1.add_feature(api.Feature('test1'))
+ conf1.add_feature(api.Feature('test2'))
+ conf1.add_feature(api.Feature('child1'),'test1')
+ dview = conf1.get_default_view()
+ dview.get_feature('test1').set_value('one')
+ dview.get_feature('test1.child1').set_value('subone')
+ conf2 = conf1._clone(recursion=True)
+ self.compareconfiguration(conf1, conf2)
+ self.assertEquals(conf2.list_all_features(),['test1', 'test1.child1', 'test2'])
+ dview2 = conf2.get_default_view()
+ self.assertEquals(dview2.get_feature('test1').get_value(),'one')
+ self.assertEquals(dview2.get_feature('test1.child1').get_value(),'subone')
+
+ def test_clone_configuration_with_includes(self):
+ conf1 = api.Configuration("testmee.confml")
+ conf1.add_feature(api.Feature('test1'))
+ conf1.add_feature(api.Feature('test2'))
+ conf1.add_feature(api.Feature('child1'),'test1')
+ conf1.create_configuration("confml/data.confml")
+ dview = conf1.get_default_view()
+ dview.get_feature('test1').set_value('one')
+ dview.get_feature('test1.child1').set_value('subone')
+ conf2 = conf1._clone(recursion=True)
+ self.compareconfiguration(conf1, conf2)
+ self.assertEquals(conf2.list_all_features(),['test1', 'test1.child1', 'test2'])
+ self.assertEquals(conf2.list_configurations(),['confml/data.confml'])
+ dview2 = conf2.get_default_view()
+ self.assertEquals(dview2.get_feature('test1').get_value(),'one')
+ self.assertEquals(dview2.get_feature('test1.child1').get_value(),'subone')
+
+# def test_create_and_get_root(self):
+# conf = api.Configuration("foobar/testmee.confml")
+# self.assertEquals(conf.get_root(),"foobar/testmee.confml")
+
+class TestCompositeConfiguration(unittest.TestCase):
+ def test_add(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ self.assertEquals(conf.list_configurations()[0],"laa")
+
+ def test_add_and_access_via_member(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ self.assertEquals(conf.laa._name,"laa")
+
+ def test_add_and_add_another_config_under(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ conf.laa._add(api.Configuration("foo"))
+ self.assertEquals(conf.laa.foo._name,"foo")
+
+ def test_add_several_configurations(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ conf._add(api.Configuration("foo"))
+ conf._add(api.Configuration("faa"))
+ self.assertEquals(conf.list_configurations()[0],"laa")
+ self.assertEquals(conf.list_configurations()[1],"foo")
+ self.assertEquals(conf.list_configurations()[2],"faa")
+
+ def test_add_several_and_remove_one_layer(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ conf._add(api.Configuration("foo"))
+ conf._add(api.Configuration("faa"))
+ conf._remove("foo")
+
+ self.assertEquals(conf.list_configurations()[0],"laa")
+ self.assertEquals(conf.list_configurations()[1],"faa")
+
+ def test_add_several_and_remove_last_layer(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ conf._add(api.Configuration("foo"))
+ conf._add(api.Configuration("faa"))
+ conf._remove("faa")
+ self.assertEquals(conf.list_configurations()[0],"laa")
+ self.assertEquals(conf.list_configurations()[1],"foo")
+
+ def test_add_several_and_remove_all_configurations(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ conf._add(api.Configuration("foo"))
+ conf._add(api.Configuration("faa"))
+ for layername in conf.list_configurations():
+ conf._remove(layername)
+
+ self.assertTrue(len(conf.list_configurations())==0)
+
+ def test_add_several_and_try_to_remove_not_existing(self):
+ conf = api.Configuration("data/simple.confml")
+ layer = api.Configuration("laa")
+ conf._add(layer)
+ conf._add(api.Configuration("foo"))
+ conf._add(api.Configuration("faa"))
+ try:
+ conf._remove("notthere")
+ self.fail("removing of nonexisting layer succeeds!")
+ except exceptions.NotFound:
+ pass
+
+ def test_add_view_simple(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.add_view("view1")
+ view = conf.get_view("view1")
+ self.assertEquals(view._list(),[])
+
+ def test_add_views_and_list_views(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.add_view("view1")
+ conf.add_view("view2")
+ self.assertEquals(conf.list_views(),['view1','view2'])
+
+ def test_add_views_and_remove_one(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.add_view("view1")
+ conf.add_view("view2")
+ conf.add_view("view3")
+ conf.remove_view('view2')
+ self.assertEquals(conf.list_views(),['view1','view3'])
+
+ def test_add_views_and_remove_invalid(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.add_view("view1")
+ conf.add_view("view2")
+ conf.add_view("view3")
+ try:
+ conf.remove_view('invalid')
+ self.fail('Removing invalid view succeeds!')
+ except exceptions.NotFound:
+ pass
+
+ def test_add_views_and_remove_all(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.add_view("view1")
+ conf.add_view("view2")
+ conf.add_view("view3")
+ for view in conf.list_views():
+ conf.remove_view(view)
+ self.assertEquals(conf.list_views(),[])
+
+ def test_add_view_with_data(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.add_view("view1")
+ view = conf.get_view("view1")
+ view._add(api.Group("group1"))
+ view._add(api.Group("group2"))
+ view._add(api._FeatureProxy("feature1"))
+ view.group1._add(api.Group("group21"))
+ view.group1.group21._add(api._FeatureProxy("feature211"))
+ view.group1.group21._add(api._FeatureProxy("feature212"))
+ view.feature1._add(api._FeatureProxy("feature11"))
+
+ self.assertEquals(sorted(view._list_traverse()),
+ sorted(['group1',
+ 'group2',
+ 'feature1',
+ 'group1.group21',
+ 'group1.group21.feature211',
+ 'group1.group21.feature212',
+ 'feature1.feature11']))
+
+ def test_get_default_view(self):
+ conf = api.Configuration("data/simple.confml")
+ dview = conf.get_default_view()
+ self.assertEquals(dview.ref,'_default_view')
+
+ def test_get_default_view_and_data_to_it(self):
+ conf = api.Configuration("data/simple.confml")
+ view = conf.get_default_view()
+ view._add(api.Group("group1"))
+ view._add(api.Group("group2"))
+ view._add(api._FeatureProxy("feature1"))
+ view.group1._add(api.Group("group21"))
+ view.group1.group21._add(api._FeatureProxy("feature211"))
+ view.group1.group21._add(api._FeatureProxy("feature212"))
+ view.feature1._add(api._FeatureProxy("feature11"))
+
+ self.assertEquals(sorted(view._list_traverse()),
+ sorted(['group1',
+ 'group2',
+ 'feature1',
+ 'group1.group21',
+ 'group1.group21.feature211',
+ 'group1.group21.feature212',
+ 'feature1.feature11']))
+
+
+ def test_add_feature_normal_configuration(self):
+ conf = api.Configuration("simple.confml")
+ conf.add_feature(api.Feature("feature1"))
+ self.assertEquals(conf.list_all_features(),['feature1'])
+
+ def test_add_feature_normal_and_get_default_view(self):
+ conf = api.Configuration("simple.confml")
+ conf.add_feature(api.Feature("feature1"))
+ conf.add_feature(api.Feature("feature2"))
+ conf.add_feature(api.Feature("feature11"),'feature1')
+ view = conf.get_default_view()
+
+ self.assertEquals(view.list_all_features(),['feature1',
+ 'feature1.feature11',
+ 'feature2',])
+ self.assertEquals(view.get_feature('feature1.feature11')._obj._parent,conf.feature1)
+
+ def test_add_feature_hierarchy_and_get_default_view(self):
+ root = api.Configuration("data/simple.confml")
+ conf = api.Configuration("test/root.confml")
+ root.add_configuration(conf)
+ conf2 = api.Configuration("test2/root.confml",namespace="com.nokia")
+ root.add_configuration(conf2)
+ conf.add_feature(api.Feature("group1"))
+ conf.add_feature(api.Feature("group2"))
+ conf.add_feature(api.Feature("feature1"))
+ conf.group1.add_feature(api.Feature("group21"))
+ conf.group1.group21.add_feature(api.Feature("feature211"))
+ conf.group1.group21.add_feature(api.Feature("feature212"))
+ conf.feature1.add_feature(api.Feature("feature11"))
+ conf2.add_feature(api.Feature("wlan"))
+ conf2.add_feature(api.Feature("bluetooth"))
+ self.assertEquals(conf.list_all_features(),
+ ['group1',
+ 'group1.group21',
+ 'group1.group21.feature211',
+ 'group1.group21.feature212',
+ 'group2',
+ 'feature1',
+ 'feature1.feature11'])
+ dview = conf.get_default_view()
+ self.assertEquals(dview.list_features(),
+ ['group1',
+ 'group2',
+ 'feature1'])
+
+ self.assertEquals(dview.list_groups(),['com'])
+ self.assertEquals(dview.list_all_features(),
+ ['group1',
+ 'group1.group21',
+ 'group1.group21.feature211',
+ 'group1.group21.feature212',
+ 'group2',
+ 'feature1',
+ 'feature1.feature11',
+ 'com.nokia.wlan',
+ 'com.nokia.bluetooth'])
+
+ def test_add_feature(self):
+ conf = api.Configuration("simple.confml")
+ conf.add_feature(api.Feature("feature1"))
+ self.assertEquals(conf.list_features(),['feature1'])
+
+# def test_add_feature_namespace(self):
+# conf = api.Configuration("test","com.nokia")
+# conf.add_feature(api.Feature("feature1"))
+# self.assertEquals(conf.list_all_features(),['com.nokia.feature1'])
+# self.assertEquals(conf.feature1, conf.get_default_view().com.nokia.feature1._obj)
+
+ def test_add_subconfiguration(self):
+ conf = api.Configuration("test",namespace="com.nokia")
+ conf.create_configuration("foo/root.confml")
+ conf.create_configuration("platforms/s60.confml")
+ self.assertEquals(conf.list_configurations(),['foo/root.confml',
+ 'platforms/s60.confml',])
+
+ def test_remove_configuration(self):
+ conf = api.Configuration("test.confml",namespace="com.nokia")
+ conf.create_configuration("foo/root.confml")
+ self.assertEquals(conf.list_configurations(),['foo/root.confml'])
+ conf.remove_configuration("foo/root.confml")
+ self.assertEquals(conf.list_configurations(),[])
+
+ def test_get_configuration(self):
+ conf = api.Configuration("test.confml",namespace="com.nokia")
+ conf.create_configuration("foo/root.confml")
+ self.assertEquals(conf.list_configurations(),['foo/root.confml'])
+ foo = conf.get_configuration("foo/root.confml")
+ self.assertEquals(foo.get_path(),"foo/root.confml")
+
+
+ def test_remove_all(self):
+ conf = api.Configuration("test",namespace="com.nokia")
+ conf.create_configuration("foo/root.confml")
+ conf.create_configuration("platforms/s60.confml")
+ conf.create_configuration("platforms/customsw.confml")
+ self.assertEquals(conf.list_configurations(),['foo/root.confml',
+ 'platforms/s60.confml',
+ 'platforms/customsw.confml'])
+ for configref in conf.list_configurations():
+ conf.remove_configuration(configref)
+ self.assertEquals(conf.list_configurations(),[])
+
+
+ def test_add_subconfiguration_and_access(self):
+ conf = api.Configuration("data/simple.confml")
+ conf.create_configuration("foo/layer1.confml")
+ self.assertTrue(conf.foo__layer1_confml)
+
+# def test_add_subconfiguration_and_features(self):
+# conf = api.Configuration("test","com.nokia")
+# conf.create_configuration("foo/root.confml")
+# conf.create_configuration("fii/root.confml")
+# conf.foo_root.add_feature(api.Feature("feature1"))
+# conf.foo_root.add_feature(api.Feature("feature12"),"feature1")
+# conf.fii_root.add_feature(api.Feature("feature2"))
+# conf.fii_root.add_feature(api.Feature("feature21"),"feature2")
+# self.assertEquals(conf.list_all_features(),['com.nokia.feature1',
+# 'com.nokia.feature1.feature12',
+# 'com.nokia.feature2',
+# 'com.nokia.feature2.feature21',
+# ])
+# self.assertEquals(conf.foo_root.feature1.get_ref(),
+# conf.get_default_view()._get('com.nokia.feature1').get_ref())
+
+ def test_add_configuration_with_features_to_root(self):
+ root= api.Configuration("test",namespace="com.nokia")
+ conf1 = api.Configuration("foo/foo.confml")
+ conf1.add_feature(api.Feature("feature1"))
+ conf1.add_feature(api.Feature("feature12"),"feature1")
+ conf2 = api.Configuration("bar/bar.confml")
+ conf2.add_feature(api.Feature("feature2"))
+ conf2.add_feature(api.Feature("feature22"),"feature2")
+ root.add_configuration(conf1)
+ self.assertEquals(root.list_all_features(),
+ ['feature1',
+ 'feature1.feature12'])
+ root.add_configuration(conf2)
+ self.assertEquals(root.list_all_features(),
+ ['feature1',
+ 'feature1.feature12',
+ 'feature2',
+ 'feature2.feature22'])
+
+ def test_add_configuration_to_other_conf_and_then_to_root(self):
+ root= api.Configuration("test",namespace="com.nokia")
+ conf1 = api.Configuration("foo/foo.confml")
+ conf1.add_feature(api.Feature("feature1"))
+ conf1.add_feature(api.Feature("feature12"),"feature1")
+ conf2 = api.Configuration("bar/foo.confml")
+ conf2.add_feature(api.Feature("feature2"))
+ conf2.add_feature(api.Feature("feature22"),"feature2")
+ conf2.add_configuration(conf1)
+ self.assertEquals(conf2.list_all_features(),
+ ['feature2',
+ 'feature2.feature22',
+ 'feature1',
+ 'feature1.feature12'])
+ root.add_configuration(conf2)
+ self.assertEquals(root.list_all_features(),
+ ['feature2',
+ 'feature2.feature22',
+ 'feature1',
+ 'feature1.feature12'])
+
+ def test_add_features_feature_hiararchy_and_then_to_configurations(self):
+ conf1 = api.Configuration("foo/foo.confml")
+ fea = api.Feature('feature1')
+ fea2 = api.Feature('feature12')
+ fea2.add_feature(api.Feature('feature121'))
+ fea.add_feature(api.Feature('feature11'))
+ fea.add_feature(fea2)
+ self.assertEquals(fea.list_all_features(),
+ ['feature11',
+ 'feature12',
+ 'feature12.feature121'])
+ conf1.add_feature(fea)
+ self.assertEquals(conf1.list_all_features(),
+ ['feature1',
+ 'feature1.feature11',
+ 'feature1.feature12',
+ 'feature1.feature12.feature121'])
+
+
+ def test_add_features_and_remove_one(self):
+ conf1 = api.Configuration("foo/foo.confml")
+ fea = api.Feature('feature1')
+ fea2 = api.Feature('feature12')
+ fea2.add_feature(api.Feature('feature121'))
+ fea.add_feature(api.Feature('feature11'))
+ fea.add_feature(fea2)
+ conf1.add_feature(fea)
+ conf1.remove_feature('feature1.feature12')
+ self.assertEquals(conf1.list_all_features(),
+ ['feature1',
+ 'feature1.feature11'])
+ fea.remove_feature('feature11')
+ self.assertEquals(conf1.list_all_features(),
+ ['feature1'])
+
+ def test_add_features_and_remove_all(self):
+ conf = api.Configuration("foo/foo.confml")
+ fea = api.Feature('feature1')
+ conf.add_feature(fea)
+ conf.add_feature(api.Feature('feature2'))
+ conf.add_feature(api.Feature('feature3'))
+ conf.add_feature(api.Feature('feature4'))
+ for fearef in conf.list_features():
+ conf.remove_feature(fearef)
+ self.assertEquals(conf.list_all_features(), [])
+
+ def test_add_features_and_create_view(self):
+
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('feature2'))
+ conf.add_feature(api.Feature('feature3'))
+ conf.add_feature(api.Feature('feature4'))
+ conf.add_feature(api.Feature('feature11'),'feature1')
+ conf.add_feature(api.Feature('feature12'),'feature1')
+
+ conf.add_view("rootfeas")
+ view = conf.get_view('rootfeas')
+ for fearef in conf.list_features():
+ fea = conf.get_feature(fearef)
+ view.add_feature(fea)
+ self.assertEquals(view.list_all_features(), ['feature1',
+ 'feature2',
+ 'feature3',
+ 'feature4'])
+ view.remove_feature('feature2')
+ self.assertEquals(view.list_all_features(), ['feature1',
+ 'feature3',
+ 'feature4'])
+
+ def test_add_features_and_create_view_with_links(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('feature2'))
+ conf.add_feature(api.Feature('feature3'))
+ conf.add_feature(api.Feature('feature4'))
+ conf.add_feature(api.Feature('feature11'),'feature1')
+ conf.add_feature(api.Feature('feature12'),'feature1')
+ conf.add_view('fea1')
+ view1 = conf.get_view('fea1')
+ view1.add_group('thegruppe1')
+ view1.get_group('thegruppe1').add(api.FeatureLink('feature1.feature11'))
+ view1.add(api.FeatureLink('feature1.*'))
+ view1.populate()
+ self.assertEquals(view1.list_all_features(),['thegruppe1.feature11','feature11','feature12'])
+ fpr = view1.get_feature('thegruppe1.feature11')
+ self.assertEquals(fpr._obj.fqr,conf.get_default_view().get_feature('feature1.feature11').fqr)
+ self.assertEquals(view1.list_all_features(), ['thegruppe1.feature11','feature11','feature12'])
+
+ def test_add_features_and_create_all_view_with_links(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('feature2'))
+ conf.add_feature(api.Feature('feature3'))
+ conf.add_feature(api.Feature('feature4'))
+ conf.add_feature(api.Feature('feature11'),'feature1')
+ conf.add_feature(api.Feature('feature12'),'feature1')
+ conf.add_view("all")
+ view1 = conf.get_view('all')
+ view1.add(api.FeatureLink('**'))
+ view1.populate()
+ self.assertEquals(view1.list_all_features(),['feature1', 'feature11', 'feature12', 'feature2', 'feature3', 'feature4'])
+ fpr = view1.get_feature('feature11')
+ self.assertEquals(fpr._obj.fqr,conf.get_default_view().get_feature('feature1.feature11').fqr)
+
+ def test_add_a_configuration_and_remove_it(self):
+ conf = api.Configuration("simple.confml")
+ conf.add_configuration(api.Configuration("confml/data.confml"))
+ self.assertEquals(conf.list_configurations(),['confml/data.confml'])
+ conf.remove_configuration("confml/data.confml")
+ self.assertEquals(len(conf.list_configurations()),0)
+
+ def test_add_a_include_and_remove_it(self):
+ conf = api.Configuration("simple.confml")
+ conf.include_configuration("confml/data.confml")
+ self.assertEquals(conf.list_configurations(),['confml/data.confml'])
+ conf.remove_configuration("confml/data.confml")
+ self.assertEquals(len(conf.list_configurations()),0)
+
+ def test_add_a_include_with_dots_in_path_and_remove_it(self):
+ conf = api.Configuration("simple.confml")
+ conf.include_configuration("test/foo.bar/data.confml")
+ self.assertEquals(conf.list_configurations(),['test/foo.bar/data.confml'])
+ conf.remove_configuration("test/foo.bar/data.confml")
+ self.assertEquals(len(conf.list_configurations()),0)
+
+ def test_add_a_include_with_dots_and_remove_it(self):
+ conf = api.Configuration("simple.confml")
+ conf.include_configuration("../foo/data.confml")
+ self.assertEquals(conf.list_configurations(),['../foo/data.confml'])
+ conf.remove_configuration("../foo/data.confml")
+ self.assertEquals(len(conf.list_configurations()),0)
+
+class TestConfigurationData(unittest.TestCase):
+ def test_add_features_and_add_data_via_default_view(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('feature2'))
+ conf.add_feature(api.Feature('feature3'))
+ conf.add_feature(api.Feature('feature4'))
+ conf.add_feature(api.Feature('feature12'),'feature1')
+ dview = conf.get_default_view()
+ dview.feature1._add_data(api.Data(ref="feature1", value=123))
+ dview.feature2._add_data(api.Data(ref="feature2", value=123))
+ dview.feature3._add_data(api.Data(ref="feature3", value=123))
+ dview.feature1.feature12._add_data(api.Data(ref="feature12", value=123))
+ dview.feature1._add_data(api.Data(ref="feature1", value=123))
+ self.assertEquals(dview.feature1.get_value(), 123)
+ dview.feature1._add_data(api.Data(ref="feature1", value=111))
+ self.assertEquals(dview.feature1.get_value(), 111)
+
+ def test_add_data_to_configuration(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_data(api.Data(ref='feature1', value=123))
+ self.assertEquals(conf.get_data('feature1').get_value(),123)
+ conf.add_data(api.Data(fqr='feature1.feature12', value="test"))
+ self.assertEquals(conf.get_data('feature1.feature12').get_value(),"test")
+ self.assertEquals(conf.data.feature1.feature12.get_value(),"test")
+ conf.remove_data('feature1.feature12')
+ self.assertEquals(conf.list_datas(), ['feature1'])
+
+ def test_set_data_to_configuration(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_data(api.Data(fqr='feature1', value=123))
+ self.assertEquals(conf.get_data('feature1').get_value(),123)
+ conf.add_data(api.Data(fqr='feature1.feature12', value="test"))
+ self.assertEquals(conf.get_data('feature1.feature12').get_value(),"test")
+ self.assertEquals(conf.data.feature1.feature12.get_value(),"test")
+
+ def test_add_features_and_add_data_via_features(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('feature2'))
+ conf.add_feature(api.Feature('feature3'))
+ conf.add_feature(api.Feature('feature4'))
+ conf.add_feature(api.Feature('feature12'),'feature1')
+ conf.feature1.set_value(123)
+ conf.feature1.feature12.set_value("test")
+ self.assertEquals(conf.feature1.get_value(),123)
+ self.assertEquals(conf.feature1.feature12.get_value(),"test")
+
+ def test_create_layers_add_features_and_add_data_via_features(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('feature2'))
+ conf.add_feature(api.Feature('feature3'))
+ conf.add_feature(api.Feature('feature4'))
+ conf.add_feature(api.Feature('feature12'),'feature1')
+ conf.feature1.set_value(123)
+ self.assertEquals(conf.feature1.get_value(),123)
+ conf.create_configuration("layer1.confml")
+ conf.feature1.feature12.set_value("test")
+ self.assertEquals(conf.feature1.get_data().find_parent(type=api.Configuration),conf)
+ self.assertEquals(conf.feature1.feature12.get_value(),"test")
+
+ conf.feature1.set_value(321)
+ conf.create_configuration("layer2.confml")
+ self.assertEquals(conf.layer2_confml.list_datas(), [])
+
+ self.assertEquals(conf.feature1.get_value(),321)
+ self.assertEquals(conf.feature1.get_data().find_parent(type=api.Configuration).get_path(),conf.get_configuration("layer1.confml").get_path())
+ self.assertEquals(conf.layer1_confml.list_all_datas(), ['feature1','feature1.feature12'])
+ self.assertEquals([data.get_value() for data in conf.layer1_confml.get_all_datas()], [321,'test'])
+ self.assertEquals(conf.list_datas(), ['feature1'])
+ self.assertEquals([data.find_parent(type=api.Configuration).get_path() for data in conf.get_all_datas()],
+ ['foo/foo.confml',
+ 'layer1.confml',
+ 'layer1.confml',])
+
+ def test_create_layers_add_featuresequence_and_add_data_via_features(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.FeatureSequence('feature1'))
+ conf.add_feature(api.Feature('child1'),'feature1')
+ conf.add_feature(api.Feature('child2'),'feature1')
+ conf.add_feature(api.Feature('child3'),'feature1')
+ conf.feature1.add_sequence()
+ conf.feature1.get_data()[0][0].set_value('test1')
+ conf.feature1.get_data()[0][1].set_value('test2')
+ conf.feature1.get_data()[0][2].set_value('test3')
+ conf.feature1.add_sequence(['foo1','foo2','foo3'])
+ self.assertEquals(conf.feature1.get_data()[1][0].get_value(),'foo1')
+ self.assertEquals(conf.feature1.get_data()[1][1].get_value(),'foo2')
+ self.assertEquals(conf.feature1.get_data()[1][2].get_value(),'foo3')
+ self.assertEquals(conf.feature1.get_value(),
+ [['test1','test2','test3'],
+ ['foo1','foo2','foo3']])
+ self.assertEquals(conf.list_all_datas(),['feature1', 'feature1.child1', 'feature1.child2', 'feature1.child3', 'feature1', 'feature1.child1', 'feature1.child2', 'feature1.child3'])
+
+ def test_create_featuresequence_and_get_empty_data(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.FeatureSequence('feature1'))
+ conf.add_feature(api.Feature('child1'),'feature1')
+ conf.add_feature(api.Feature('child2'),'feature1')
+ conf.add_feature(api.Feature('child3'),'feature1')
+ self.assertEquals(conf.get_feature('feature1').get_data(),[])
+ self.assertEquals(conf.get_feature('feature1').get_value(),[])
+
+ def test_create_featuresequence_and_set_template(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.FeatureSequence('feature1'))
+ conf.add_feature(api.Feature('child1'),'feature1')
+ conf.add_feature(api.Feature('child2'),'feature1')
+ conf.add_feature(api.Feature('child3'),'feature1')
+ fea = conf.get_feature('feature1')
+ fea.set_template(['test1','test2','test3'])
+ self.assertEquals(fea.get_template(),['test1', 'test2', 'test3'])
+ fea.set_template(['test1','test3'])
+ self.assertEquals(fea.get_template(),['test1','test3','test3'])
+ try:
+ fea.set_template(['test1',None,'test3',None])
+ self.fail("Able to add more data then allowed")
+ except IndexError:
+ pass
+
+ def test_create_features_with_rfs_data(self):
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.Feature('feature1'))
+ conf.add_feature(api.Feature('child1'),'feature1')
+ conf.add_feature(api.Feature('child2'),'feature1')
+ conf.add_feature(api.Feature('child3'),'feature1')
+
+ conf.add_data(api.Data(fqr='feature1.child1',attr='rfs',value='true'))
+ conf.add_data(api.Data(fqr='feature1.child2',attr='rfs',value='false'))
+ dview = conf.get_default_view()
+ self.assertEquals(dview.get_feature('feature1.child1').get_value(), None)
+ self.assertEquals(dview.get_feature('feature1.child1').get_value('rfs'), 'true')
+ self.assertEquals(dview.get_feature('feature1.child2').get_value('rfs'), 'false')
+
+class TestConfigurationDictStoring(unittest.TestCase):
+
+ def test_dumps_simple(self):
+ root = api.Configuration("root",namespace="com.nokia")
+ conf = root.create_configuration("test.confml")
+ dumped = persistentdictionary.DictWriter().dumps(conf)
+ dict =dumped['Configuration']['dict']
+ self.assertEquals(dict['path'],'test.confml')
+ self.assertEquals(dict['namespace'],'com.nokia')
+
+ def test_dumps_add_features(self):
+ root = api.Configuration("root",namespace="com.nokia")
+ conf = root.create_configuration("test.confml")
+ conf.add_feature(api.Feature("feature1"))
+ conf.add_feature(api.Feature("feature2"))
+ dumped = persistentdictionary.DictWriter().dumps(conf)
+ dict =dumped['Configuration']['dict']
+ self.assertEquals(dict['path'],'test.confml')
+ self.assertEquals(dict['namespace'],'com.nokia')
+ self.assertEquals(dumped['Configuration']['children'],
+ [{'Feature': {'dict': {'name': 'feature1', 'ref': 'feature1'}}},
+ {'Feature': {'dict': {'name': 'feature2', 'ref': 'feature2'}}}]
+ )
+
+ def test_dumps_root_configuration(self):
+ root = api.Configuration("root",namespace="com.nokia")
+ conf = root.create_configuration("test.confml")
+ conf = root.create_configuration("foo/root.confml")
+ conf.add_feature(api.Feature("feature1"))
+ conf.add_feature(api.Feature("feature2"))
+ conf.feature1.add_feature(api.Feature("feature11"))
+ conf.feature1.add_feature(api.Feature("feature12"))
+ dumped = persistentdictionary.DictWriter().dumps(root)
+ dict =dumped['Configuration']['dict']
+ self.assertEquals(dict['ref'],'root')
+ self.assertEquals(dict['namespace'],'com.nokia')
+
+ def test_dumps_feature_hierarchy(self):
+ root = api.Configuration("root",namespace="com.nokia")
+ conf = root.create_configuration("test.confml")
+ conf.add_feature(api.Feature("feature1"))
+ conf.add_feature(api.Feature("feature2"))
+ conf.feature1.add_feature(api.Feature("feature11"))
+ conf.feature1.add_feature(api.Feature("feature12"))
+ dumped = persistentdictionary.DictWriter().dumps(conf)
+ dict =dumped['Configuration']['dict']
+ self.assertEquals(dict['path'],'test.confml')
+ self.assertEquals(dict['ref'],'test_confml')
+ self.assertEquals(dict['namespace'],'com.nokia')
+ self.assertEquals(dumped['Configuration']['children'],
+ [{'Feature': {'dict': {'name': 'feature1', 'ref': 'feature1'},
+ 'children': [
+ {'Feature': {'dict': {'name': 'feature11', 'ref': 'feature11'}}},
+ {'Feature': {'dict': {'name': 'feature12', 'ref': 'feature12'}}}]}},
+ {'Feature': {'dict': {'name': 'feature2', 'ref': 'feature2'}}}
+ ])
+
+ def test_loads(self):
+ conf = persistentdictionary.DictReader().loads({'Configuration': {'dict' : {'namespace':'test','ref':'test.confml'}}} )
+ self.assertTrue(isinstance(conf,api.Configuration))
+ self.assertEquals(conf.namespace,'test')
+ self.assertEquals(conf.get_ref(),'test.confml')
+
+ def test_loads_with_features(self):
+ root = api.Configuration("root",namespace="com.nokia")
+ conf = persistentdictionary.DictReader().loads({
+ 'Configuration': {'dict' : {'namespace':'test','ref':'test.confml'},
+ 'children': [{'Feature': {'dict': {'ref': 'feature1'},
+ 'children': [
+ {'Feature': {'dict': {'ref': 'feature11'}}},
+ {'Feature': {'dict': {'ref': 'feature12'}}}]
+ }
+ },
+ {'Feature': {'dict': {'ref': 'feature2'}}}]}} )
+
+ self.assertEquals(conf.namespace,'test')
+ self.assertEquals(conf.ref,'test.confml')
+ root.add_configuration(conf)
+ self.assertEquals(root.list_all_features(),['test.feature1',
+ 'test.feature1.feature11',
+ 'test.feature1.feature12',
+ 'test.feature2'])
+
+
+ def test_dumps_and_loads(self):
+ conf = api.Configuration("test.confml")
+ conf.add_feature(api.Feature("feature1"))
+ conf.add_feature(api.Feature("feature2"))
+ conf.feature1.add_feature(api.Feature("feature11"))
+ conf.feature1.add_feature(api.Feature("feature12"))
+ dumped = persistentdictionary.DictWriter().dumps(conf)
+
+ conf2 = persistentdictionary.DictReader().loads(dumped)
+ self.assertEquals(conf.list_all_features(),
+ conf2.list_all_features())
+
+ def test_dumps_and_loads_configuration_hierarchy(self):
+ root = api.Configuration("root.confml")
+ root.add_configuration(api.Configuration("layer1.confml"))
+ layer = api.Configuration("foo/layer2.confml")
+ conf = api.Configuration("foo/test.confml")
+ conf.add_feature(api.Feature("feature1"))
+ conf.add_feature(api.Feature("feature2"))
+ conf.feature1.add_feature(api.Feature("feature11"))
+ conf.feature1.add_feature(api.Feature("feature12"))
+ layer.add_configuration(conf)
+ root.add_configuration(layer)
+ dumped = persistentdictionary.DictWriter().dumps(root)
+
+ root2= persistentdictionary.DictReader().loads(dumped)
+ self.assertEquals(root.list_all_features(),
+ root2.list_all_features())
+
+ def test_dumps_and_loads_configuration_hierarchy_with_data(self):
+ root = api.Configuration("root.confml")
+ layer = api.Configuration("foo/layer1.confml")
+ conf = api.Configuration("foo/test.confml")
+ conf.add_feature(api.Feature("feature1"))
+ conf.add_feature(api.Feature("feature2"))
+ conf.feature1.add_feature(api.Feature("feature11"))
+ conf.feature1.add_feature(api.Feature("feature12"))
+ conf.feature1.set_value(1)
+ conf.feature2.set_value(2)
+ layer.add_configuration(conf)
+ root.add_configuration(layer)
+ root.add_configuration(api.Configuration("layer2.confml"))
+ root.get_default_view().feature1.feature11.set_value("testing11")
+ root.get_default_view().feature1.set_value("test1")
+ dumped = persistentdictionary.DictWriter().dumps(root)
+ root2= persistentdictionary.DictReader().loads(dumped)
+ self.assertEquals(root.list_all_features(),
+ root2.list_all_features())
+ self.assertEquals(root2.get_default_view().feature1.get_value(), "test1")
+ self.assertEquals(root2.get_default_view().feature2.get_value(), 2)
+ self.assertEquals(root2.get_default_view().feature1.feature11.get_value(), "testing11")
+
+ self.assertEquals([data.find_parent(type=api.Configuration).get_path() for data in root2.get_all_datas()],
+ ['foo/test.confml', 'foo/test.confml', 'layer2.confml','layer2.confml'])
+
+ def test_access_via_configuration_proxy(self):
+ conf = api.Configuration("root.confml")
+ conf.add_feature(api.Feature("feature1"))
+ proxy = api.ConfigurationProxy("root.confml")
+ proxy.set('_obj',conf)
+ self.assertEquals(proxy.get_ref(), 'root_confml')
+ self.assertEquals(proxy.get_path(), 'root.confml')
+ self.assertEquals(conf.feature1.get_ref(), 'feature1')
+ self.assertEquals(proxy.feature1.get_ref(), 'feature1')
+
+
+if __name__ == '__main__':
+ unittest.main()
+
+"""
+{'Configuration': {'dict': {'path': 'root.confml', 'ref': 'root', 'namespace': '', 'desc': ''}, 'children': [{'Configuration': {'dict': {'path': 'foo/layer1.confml', 'ref': 'foo_layer1', 'namespace': '', 'desc': ''}, 'children': [{'Configuration': {'dict': {'path': 'foo/test.confml', 'ref': 'foo_test', 'namespace': '', 'desc': ''}, 'children': [{'Feature': {'dict': {'ref': 'feature1'}, 'children': [{'Feature': {'dict': {'ref': 'feature11'}}}, {'Feature': {'dict': {'ref': 'feature12'}}}]}}, {'Feature': {'dict': {'ref': 'feature2'}}}, {'DataContainer': {'dict': {'ref': 'data'}, 'children': [{'Data': {'dict': {'ref': 'feature1', 'value': 1}}}, {'Data': {'dict': {'ref': 'feature2', 'value': 2}}}]}}]}}]}}, {'Configuration': {'dict': {'path': 'layer2.confml', 'ref': 'layer2', 'namespace': '', 'desc': ''}}}]}}
+"""
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_container.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_container.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,574 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import zipfile
+import unittest
+import string
+import sys,os,re
+import __init__
+
+from cone.public import utils, container, exceptions
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+importpk = os.path.join(ROOT_PATH,"Import.pk")
+
+
+class TestC(object):
+ def __init__(self, path=""):
+ self.path = path
+ def test(self):
+ return "test string"
+class TestB(object):
+ def __init__(self, path=""):
+ self.path = path
+ def test(self):
+ return "test string"
+
+
+class TestDataContainer(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_add_values_and_get_values(self):
+ cont = container.DataContainer()
+ cont.add_value('test/ff',123)
+ cont.add_value('test/ff','test')
+ self.assertEquals(cont.get_value('test/ff'),'test')
+ self.assertEquals(cont.get_values('test/ff')[0],123)
+ self.assertEquals(cont.get_values('test/ff')[1],'test')
+
+ def test_add_values_and_list_values(self):
+ cont = container.DataContainer()
+ cont.add_value('test/ff',123)
+ cont.add_value('test/ff','test')
+ cont.add_value('test/foo','test')
+ keys = cont.list_keys()
+ self.assertEquals(len(keys),2)
+
+ def test_add_values_and_remove_one_value(self):
+ cont = container.DataContainer()
+ cont.add_value('test/ff',123)
+ cont.add_value('test/ff','test')
+ cont.add_value('test/foo','test')
+ cont.add_value('test/foo','123')
+ cont.add_value('sss',123)
+ cont.remove_value('test/foo','test')
+ self.assertEquals(cont.get_values('test/foo'),['123'])
+
+ def test_add_values_and_remove_all_values_of_a_key(self):
+ cont = container.DataContainer()
+ cont.add_value('test/ff',123)
+ cont.add_value('test/ff','test')
+ cont.add_value('test/foo','test')
+ cont.add_value('test/foo','123')
+ cont.add_value('test/foo','foobar')
+ cont.add_value('sss',123)
+ for val in cont.get_values('test/foo'):
+ cont.remove_value('test/foo',val)
+ self.assertEquals(cont.get_values('test/foo'),[])
+
+ def test_add_values_and_remove_key(self):
+ cont = container.DataContainer()
+ cont.add_value('test/ff',123)
+ cont.add_value('test/ff','test')
+ cont.add_value('test/foo','test')
+ cont.add_value('test/foo','123')
+ cont.add_value('test/foo','foobar')
+ cont.add_value('sss',123)
+ cont.remove_key('test/foo')
+ self.assertEquals(cont.list_keys(),['test/ff','sss'])
+
+ def test_add_values_clear_all_data(self):
+ cont = container.DataContainer()
+ cont.add_value('test/ff',123)
+ cont.add_value('test/ff','test')
+ cont.add_value('test/foo','test')
+ cont.add_value('test/foo','123')
+ cont.clear()
+ self.assertEquals(len(cont.list_keys()),0)
+
+ def test_conatainer_flatten(self):
+ data = container.DataContainer()
+ data.add_value('test', 1)
+ data.add_value('test', 2)
+ data.add_value('test', 3)
+ data.add_value('foo', 1)
+ data.add_value('foo', 2)
+ data.add_value('bar', 3)
+ self.assertEquals(data.flatten(),{'test': 3, 'foo' : 2,'bar': 3})
+
+
+
+class TestObjectProxy(unittest.TestCase):
+ def test_create_object_proxy_for_test(self):
+ cont = container.ObjectProxy(TestC("foo"))
+ self.assertTrue(cont)
+ self.assertEquals(cont.test(),"test string")
+
+ def test_create_none_proxy(self):
+ cont = container.ObjectProxy("")
+ self.assertTrue(cont)
+ try:
+ cont.test()
+ self.fail("calling None succeeds?")
+ except AttributeError:
+ pass
+
+ def test_create_object_proxy_for_string(self):
+ cont = container.ObjectProxy("test string")
+ self.assertTrue(cont)
+ self.assertEquals(cont.startswith("test"),True)
+
+
+def graph(obj):
+ if obj._parent:
+ return ["%s -> %s" % (obj._parent._name, obj._name)]
+ return []
+
+class TestObjectContainer(unittest.TestCase):
+ def test_create_object_container(self):
+ cont = container.ObjectContainer("test")
+ self.assertTrue(cont)
+
+ def test_add_incorrect_type(self):
+ cont = container.ObjectContainer()
+ try:
+ cont._add(container.ObjectProxy())
+ self.fail("Adding incorrect class type to container succeeds?")
+ except exceptions.IncorrectClassError,e:
+ pass
+
+
+ def test_add_child(self):
+ cont = container.ObjectContainer("root")
+ obj = container.ObjectContainer("test")
+ cont._add(obj)
+ cont._add(container.ObjectContainer("foo"))
+ self.assertEquals(cont._list(),['test','foo'])
+ self.assertEquals(cont.test,obj)
+
+ def test_add_internal_child(self):
+ cont = container.ObjectContainer("root")
+ obj = container.ObjectContainer("?test")
+ cont._add(obj)
+ cont._add(container.ObjectContainer("foo"))
+ self.assertEquals(cont._list(),['foo'])
+ self.assertEquals(cont._get('?test'),obj)
+
+
+ def test_add_child_to_path(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ self.assertEquals(cont._list(),['com'])
+ self.assertEquals(cont.com.nokia._list(),['test'])
+ self.assertEquals(cont.com.nokia.test,obj)
+
+ def test_add_child_to_path_and_replace_parent(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ com = container.ObjectContainer("com")
+ cont._add(com)
+ self.assertEquals(cont._list(),['com'])
+ self.assertEquals(cont.com._list(),['nokia','bar'])
+ self.assertEquals(cont.com.bar._parent,com)
+ self.assertEquals(cont.com.nokia._list(),['test'])
+ self.assertEquals(cont.com.nokia.test,obj)
+
+ def test_append(self):
+ cont = container.ObjectContainer("test")
+ cont._append(container.ObjectContainer('test'))
+ self.assertEquals(len(utils.get_list(cont.test)), 1)
+ cont._append(container.ObjectContainer('test'))
+ self.assertEquals(len(cont.test), 2)
+
+ def test_prepend(self):
+ cont = container.ObjectContainer("test")
+ cont._prepend(container.ObjectContainer('test'))
+ self.assertEquals(len(utils.get_list(cont.test)), 1)
+ cont._prepend(container.ObjectContainer('test'))
+ self.assertEquals(len(cont.test), 2)
+
+ def test_replace(self):
+ cont = container.ObjectContainer("test")
+ t1 = container.ObjectContainer('test')
+ cont._replace(t1)
+ self.assertEquals(cont.test, t1)
+ t2 = container.ObjectContainer('test')
+ cont._replace(t2)
+ self.assertEquals(cont.test, t2)
+
+ def test_error(self):
+ cont = container.ObjectContainer("test")
+ t1 = container.ObjectContainer('test')
+ cont._error(t1)
+ self.assertEquals(cont.test, t1)
+ t2 = container.ObjectContainer('test')
+ try:
+ cont._error(t2)
+ self.fail("adding same with error succeeds")
+ except exceptions.AlreadyExists, e:
+ pass
+
+ def test_add_child_to_existing_path_with_error(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ com = container.ObjectContainer("com")
+ try:
+ cont._add(com, policy=container.ERROR)
+ self.fail("Adding an existing object succeeds with ERROR policy")
+ except exceptions.AlreadyExists, e:
+ pass
+
+ def test_add_child_to_existing_path_append(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"), container.APPEND)
+ com = container.ObjectContainer("com")
+ cont._add(com, policy=container.APPEND)
+ self.assertEquals(len(cont._get('com')),2)
+ self.assertEquals(cont._get('com')[1],com)
+ self.assertEquals(len(cont._objects()),2)
+ self.assertEquals(len(cont.com[0].nokia.test),2)
+ self.assertEquals(len(cont._get('com[0].nokia.test')),2)
+ self.assertEquals([e._name for e in cont._traverse()],['com', 'nokia', 'test', 'test', 'com'])
+
+ def test_add_child_to_existing_path_append_and_objects(self):
+ cont = container.ObjectContainer("test")
+ cont._add(container.ObjectContainer("dummy"),container.APPEND)
+ cont._add(container.ObjectContainer("child"),container.APPEND)
+ cont._add(container.ObjectContainer("child"),container.APPEND)
+ cont._add(container.ObjectContainer("child"),container.APPEND)
+ self.assertEquals(len(cont._objects()),4)
+ cont._remove('child[1]')
+ self.assertEquals(len(cont._objects()),3)
+ cont._remove('child[0]')
+ cont._remove('child[0]')
+ self.assertEquals(len(cont._objects()),1)
+
+ def test_add_child_and_access_via_index(self):
+ cont = container.ObjectContainer("test")
+ cont._add(container.ObjectContainer("dummy"),container.APPEND)
+ d1 = cont._get('dummy')
+ d2 = cont._get('dummy[0]')
+ self.assertEquals(d1,d2)
+ try:
+ cont._get('dummy[1]')
+ self.fail("getting dummy")
+ except exceptions.NotFound:
+ pass
+
+ def test_add_child_to_existing_path_append_and_remove(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ com = container.ObjectContainer("com")
+ cont._add(com, policy=container.APPEND)
+ self.assertEquals(len(cont._get('com')),2)
+ self.assertEquals(cont._get('com')[1],com)
+ self.assertEquals(cont._list(),['com'])
+ cont._remove('com')
+ self.assertEquals(cont._list(), [])
+
+ def test_add_child_to_existing_path_prepend(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ com = container.ObjectContainer("com")
+ cont._add(com, policy=container.PREPEND)
+ self.assertEquals(len(cont._get('com')),2)
+ self.assertEquals(cont._get('com')[0],com)
+
+ def test_add_child_and_get(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ self.assertEquals(cont._get('com.nokia.test'),obj)
+ self.assertEquals(cont.com._get('nokia.test'),obj)
+ self.assertEquals(cont.com.nokia._get('test'),obj)
+
+ def test_add_child_and_remove_one(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ self.assertEquals(len(cont._traverse()),5)
+ cont._remove("com.nokia.foo")
+ self.assertEquals(len(cont._traverse()),4)
+
+ def test_add_child_and_remove_all(self):
+ cont = container.ObjectContainer("test")
+ obj = container.ObjectContainer("test")
+ cont._add_to_path("com.nokia", obj)
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ self.assertEquals(len(cont._traverse()),5)
+ for item in cont._list():
+ cont._remove(item)
+ self.assertEquals(len(cont._list()),0)
+
+ def test_add_children_and_list_all(self):
+ cont = container.ObjectContainer("test")
+ obj = TestC()
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ self.assertEquals(len(cont._traverse()),5)
+
+ def test_create_hieararchy_and_remove_child(self):
+ root = container.ObjectContainer("test")
+ root._add(container.ObjectContainer("child1"))
+ root._add(container.ObjectContainer("child2"))
+ root.child1._add(container.ObjectContainer("child11"))
+ root.child1._add(container.ObjectContainer("child12"))
+ root.child2._add(container.ObjectContainer("child21"))
+ self.assertEquals(root._list_traverse(),
+ ['child1',
+ 'child1.child11',
+ 'child1.child12',
+ 'child2',
+ 'child2.child21'])
+ root.child2._remove('child21')
+ self.assertEquals(root._list_traverse()
+ ,['child1',
+ 'child1.child11',
+ 'child1.child12',
+ 'child2'])
+
+ def test_add_children_and_traverse_and_get_path(self):
+ cont = container.ObjectContainer("default")
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ cont.com._list()
+ self.assertEquals(cont._traverse()[0]._path(),"default.com")
+ self.assertEquals(cont._traverse()[0]._path(cont),"com")
+ self.assertEquals(cont._traverse()[0]._path(cont.com),"")
+
+ def test_add_children_and_traverse_filter_name_and_get_path(self):
+ cont = container.ObjectContainer("default")
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ cont.com._list()
+ ret = cont._traverse(name="^t.*$")
+ self.assertEquals(len(ret),1)
+ self.assertEquals(ret[0]._path(),"default.com.nokia.test")
+
+ def test_add_children_and_traverse_filter_name_many(self):
+ cont = container.ObjectContainer("default")
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ cont.com._list()
+ ret = cont._traverse(path=".*nokia.*")
+ self.assertEquals(len(ret),3)
+ self.assertEquals(ret[0]._path(),"default.com.nokia")
+
+ def test_add_children_tail_recurse_with_function(self):
+ cont = container.ObjectContainer("default")
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ ret = cont._tail_recurse(graph)
+ self.assertEquals(ret,['default -> com', 'com -> nokia', 'nokia -> test', 'nokia -> foo', 'com -> bar'])
+
+ def test_add_children_head_recurse_with_function(self):
+ cont = container.ObjectContainer("default")
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ ret = cont._head_recurse(graph)
+ self.assertEquals(ret,['nokia -> test', 'nokia -> foo', 'com -> nokia', 'com -> bar', 'default -> com'])
+
+ def test_add_children_and_find_parent(self):
+ cont = container.ObjectContainer("default", container=True)
+ cont._add(container.ObjectContainer("com",housut="test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("test"))
+ cont._add_to_path("com.nokia", container.ObjectContainer("foo"))
+ cont._add_to_path("com", container.ObjectContainer("bar"))
+ child = cont._get('com.nokia.test')
+ self.assertEquals(child._find_parent()._name, 'nokia')
+ self.assertEquals(child._find_parent(container=True)._name, 'default')
+ self.assertEquals(child._find_parent(housut="test")._name, 'com')
+ self.assertEquals(child._find_parent(__class__=container.ObjectContainer)._name, 'nokia')
+ self.assertEquals(child._find_parent(type=container.ObjectContainer)._name, 'nokia')
+
+class TestObjectProxyContainer(unittest.TestCase):
+ def test_create_object_container_for_test(self):
+ cont = container.ObjectProxyContainer(TestC("foo"))
+ self.assertTrue(cont)
+ self.assertEquals(cont.test(),"test string")
+
+ def test_create_none_container(self):
+ cont = container.ObjectProxyContainer(None)
+ self.assertTrue(cont)
+ try:
+ cont.test()
+ self.fail("calling None succeeds?")
+ except AttributeError:
+ pass
+
+ def test_create_object_container_for_string(self):
+ cont = container.ObjectProxyContainer("Test")
+ self.assertTrue(cont)
+ self.assertEquals(cont.startswith("Test"),True)
+
+ def test_create_object_container(self):
+ cont = container.ObjectProxyContainer(TestC())
+ self.assertTrue(cont)
+
+ def test_add_child(self):
+ cont = container.ObjectProxyContainer(None)
+ obj = TestC()
+ cont._add(container.ObjectProxyContainer(obj,"test"))
+ self.assertEquals(cont._list(),['test'])
+ self.assertEquals(cont.test._obj,obj)
+
+ def test_add_child_to_path(self):
+ cont = container.ObjectProxyContainer(None)
+ obj = TestC()
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(obj,"test"))
+ self.assertEquals(cont._list(),['com'])
+ self.assertEquals(cont.com.nokia._list(),['test'])
+ self.assertEquals(cont.com.nokia.test._obj,obj)
+ self.assertEquals(cont.com.nokia.test.test(),"test string")
+
+ def test_add_child_and_get(self):
+ cont = container.ObjectProxyContainer(None)
+ obj = TestC()
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(obj,"test"))
+ self.assertEquals(cont._get('com.nokia.test')._obj,obj)
+ self.assertEquals(cont.com._get('nokia.test')._obj,obj)
+ self.assertEquals(cont.com.nokia._get('test')._obj,obj)
+
+ def test_add_child_and_remove_one(self):
+ cont = container.ObjectProxyContainer(None)
+ obj = TestC()
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(obj,"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+
+ self.assertEquals(len(cont._traverse()),5)
+ cont._remove("com.nokia.foo")
+ self.assertEquals(len(cont._traverse()),4)
+
+ def test_add_child_and_remove_all(self):
+ cont = container.ObjectProxyContainer(None)
+ obj = TestC()
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(obj,"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+ self.assertEquals(len(cont._traverse()),5)
+ for item in cont._list():
+ cont._remove(item)
+ self.assertEquals(len(cont._list()),0)
+
+ def test_add_children_and_list_all(self):
+ cont = container.ObjectProxyContainer(None)
+ obj = TestC()
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(obj,"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+ self.assertEquals(len(cont._traverse()),5)
+
+ def test_add_children_and_traverse_and_get_path(self):
+ cont = container.ObjectProxyContainer(None,"default")
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+ cont.com._list()
+ self.assertEquals(cont._traverse()[0]._path(),"default.com")
+
+ def test_add_children_and_traverse_filter_name_and_get_path(self):
+ cont = container.ObjectProxyContainer(None,"default")
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+ cont.com._list()
+ ret = cont._traverse(name="^t.*$")
+ self.assertEquals(len(ret),1)
+ self.assertEquals(ret[0]._path(),"default.com.nokia.test")
+
+ def test_add_children_and_traverse_filter_name_many(self):
+ cont = container.ObjectProxyContainer(None,"default")
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+ cont.com._list()
+ ret = cont._traverse(path=".*nokia.*")
+ self.assertEquals(len(ret),3)
+ self.assertEquals(ret[0]._path(),"default.com.nokia")
+
+ def test_add_children_and_traverse_filter_class(self):
+ cont = container.ObjectProxyContainer(None,"default")
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestB(),"bee"))
+ cont.com.nokia._add(container.ObjectProxyContainer(TestB(),"vee"))
+ ret = cont._traverse(filters=[lambda x: hasattr(x,'_obj') and isinstance(x._obj, TestB)])
+ self.assertEquals(len(ret),2)
+ self.assertEquals(ret[0]._path(cont),"com.nokia.bee")
+ self.assertEquals(ret[1]._path(cont),"com.nokia.vee")
+
+ def test_add_children_and_traverse_filter_class_proxies(self):
+ cont = container.ObjectProxyContainer(None,"default")
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"test"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestC(),"foo"))
+ cont._add_to_path("com", container.ObjectProxyContainer(TestC(),"bar"))
+ cont._add_to_path("com.nokia", container.ObjectProxyContainer(TestB(),"bee"))
+ cont.com.nokia._add(container.ObjectProxyContainer(TestB(),"vee"))
+ ret = cont._traverse(filters=[lambda x: isinstance(x, container.ObjectProxyContainer)])
+ self.assertEquals(len(ret),5)
+ self.assertEquals(ret[0]._path(cont),"com.nokia.test")
+ self.assertEquals(ret[1]._path(cont),"com.nokia.foo")
+
+class TestLoadProxy(unittest.TestCase):
+ def test_create_load_proxy(self):
+ proxy = container.LoadProxy(importpk, container.LoadInterface())
+ proxy._load()
+ self.assertTrue(proxy._obj != None)
+
+ def test_create_load_proxy_and_get(self):
+ proxy = container.LoadProxy(importpk, container.LoadInterface())
+ self.assertEquals(proxy.list_resources(''),['test1.txt', 'test2.txt', 'test3.txt'])
+ self.assertTrue(proxy._obj != None)
+
+ def test_create_load_proxy_and_unload(self):
+ proxy = container.LoadProxy(importpk, container.LoadInterface())
+ self.assertEquals(proxy.list_resources(''),['test1.txt', 'test2.txt', 'test3.txt'])
+ proxy.set('path',"unload.pk")
+ proxy._unload()
+ self.assertTrue(proxy._obj == None)
+ proxy =None
+ proxy2 = container.LoadProxy("unload.pk", container.LoadInterface())
+ self.assertEquals(proxy2.list_resources(''),['test1.txt', 'test2.txt', 'test3.txt'])
+ os.unlink("unload.pk")
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_data.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_data.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,119 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public import api,exceptions,utils, container
+
+class TestData(unittest.TestCase):
+ # @test
+ def test_create_data(self):
+ data = api.Data(fqr="foo", value=123)
+ self.assertTrue(data)
+ data = api.Data(fqr="foo.bar", value=123, attr='rfs')
+ self.assertEquals(data.attr,'rfs')
+ data = api.Data(fqr="foo.bar", value=123, attr=None)
+ self.assertEquals(data.attr,'data')
+ data = api.Data(fqr="foo.bar", value=123, attr='data')
+ self.assertEquals(data.attr,'data')
+
+ def test_create_data_with_map(self):
+ data = api.Data(ref="StringToString", map="StringToStringSequenceFeature/SequenceSetting[@key='Key 1']")
+ self.assertEqual(data.get_map(),"StringToStringSequenceFeature/SequenceSetting[@key='Key 1']")
+ self.assertEqual(data.get_map_ref(),"StringToStringSequenceFeature/SequenceSetting")
+ self.assertEqual(data.get_map_key_value(),"Key 1")
+ self.assertTrue(data)
+
+ def test_create_data_getters(self):
+ data = api.Data(ref="foo", value=123)
+ self.assertEquals(data.fqr, "foo")
+ data = api.Data(fqr="foo.bar.test", value=123)
+ self.assertEquals(data.get_ref(), "test")
+ self.assertEquals(data.get_value(), 123)
+ self.assertEquals(data.get_policy(), "")
+
+ def test_create_data_for_sequences(self):
+ data = api.Data(ref="seq")
+ data._add(api.Data(ref="foo", value='sss'),container.APPEND)
+ data._add(api.Data(ref="foo", value='aaa'),container.APPEND)
+ data._add(api.Data(ref="foo", value=123),container.PREPEND)
+
+ self.assertEquals(data.fqr, "seq")
+ self.assertEquals(data._get('foo[0]').get_ref(), "foo")
+ self.assertEquals(data._get('foo[0]').fqr, "seq.foo")
+ self.assertEquals(data.foo[0].get_value(), 123)
+ self.assertEquals(data.foo[0].get_index(), 0)
+ self.assertEquals(data.foo[1].get_value(), 'sss')
+ self.assertEquals(data.foo[1].get_index(), 1)
+ self.assertEquals(data.foo[2].get_value(), 'aaa')
+ self.assertEquals(data.foo[2].get_index(), 2)
+ data._add(api.Data(ref="foo", value='NEW'))
+ self.assertEquals(data.foo.get_value(), 'NEW')
+
+ def test_create_configuration_with_data(self):
+ config = api.Configuration("dataconf")
+ config.add_data(api.Data(fqr='foo.setting1',value=123))
+ config.add_data(api.Data(fqr='foo.setting2',value=456))
+ config.add_data(api.Data(fqr='foo.seq.data1',value='juhuu'))
+ config.add_data(api.Data(fqr='foo.seq.data2',value='x:\\ss'))
+ self.assertEquals(config.data.foo.setting1.get_value(), 123)
+ self.assertEquals(config.data.foo.setting1.fqr, 'foo.setting1')
+ self.assertEquals(config.data.foo.seq.data2.fqr, 'foo.seq.data2')
+ self.assertEquals(config.data.foo.seq.data2.get_ref(), 'data2')
+ self.assertEquals(config.get_data('foo.seq.data2').get_value(), 'x:\\ss')
+
+ def comparedata(self,data1,data2):
+ self.assertEquals(data1.ref, data1.ref)
+ self.assertEquals(data1.fqr, data1.fqr)
+ self.assertEquals(data1.value, data1.value)
+
+ def test_clone_data(self):
+ data1 = api.Data(ref="dat")
+ data2 = data1._clone()
+ self.comparedata(data1, data2)
+
+ def test_clone_hierarchical_data(self):
+ data1 = api.Data(ref="seq")
+ data1._add(api.Data(ref="foo1", value='sss'))
+ data1._add(api.Data(ref="foo2", value='aaa'))
+ data1._add(api.Data(ref="foo3", value=123))
+
+ data2 = data1._clone(recursion=True)
+ self.comparedata(data1, data2)
+ self.comparedata(data1.foo1, data2.foo1)
+ self.comparedata(data1.foo2, data2.foo2)
+ self.comparedata(data1.foo3, data2.foo3)
+
+ def test_clone_sequential_data(self):
+ data1 = api.Data(ref="seq")
+ data1._add(api.Data(ref="foo", value='sss'),container.APPEND)
+ data1._add(api.Data(ref="foo", value='aaa'),container.APPEND)
+ data1._add(api.Data(ref="foo", value=123),container.APPEND)
+
+ data2 = data1._clone(recursion=True)
+ self.comparedata(data1, data2)
+ self.comparedata(data1.foo[0], data2.foo[0])
+ self.comparedata(data1.foo[1], data2.foo[1])
+ self.comparedata(data1.foo[2], data2.foo[2])
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_feature.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_feature.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,475 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public import api,exceptions,utils
+
+
+class TestFeature(unittest.TestCase):
+ def comparefeatures(self,fea1,fea2):
+ self.assertEquals(fea1.ref, fea2.ref)
+ self.assertEquals(fea1.fqr, fea2.fqr)
+ self.assertEquals(fea1.name, fea2.name)
+ self.assertEquals(fea1.type, fea2.type)
+
+ def test_create_feature(self):
+ fea= api.Feature("foo")
+ self.assertTrue(fea)
+
+ def test_get_namespace(self):
+ fea= api.Feature("foo")
+ self.assertTrue(fea)
+ self.assertEquals(fea.namespace,"")
+
+ def test_get_ref(self):
+ fea= api.Feature("foo")
+ self.assertTrue(fea)
+ self.assertEquals(fea.get_ref(),"foo")
+
+ def test_create_config_with_namespace_and_get_fqr(self):
+ conf = api.Configuration("test.confml", namespace="com.nokia.s60")
+ conf.add_feature(api.Feature("foo"))
+ fea= conf.get_feature("foo")
+ self.assertEquals(fea.namespace,"com.nokia.s60")
+ self.assertEquals(fea.fqr,"com.nokia.s60.foo")
+
+ def test_set_ref_and_get_all(self):
+ conf = api.Configuration("test.confml", namespace="com.nokia.s60")
+ conf.add_feature(api.Feature("foo"))
+ fea = conf.get_feature("foo")
+ fea.set_ref("wlan")
+ self.assertEquals(fea.get_ref(),"wlan")
+ self.assertEquals(fea.namespace,"com.nokia.s60")
+ self.assertEquals(fea.fqr,"com.nokia.s60.wlan")
+
+ def test_create_subfeature_and_get_namespace(self):
+ fea= api.Feature("foo")
+ fea.add_feature(api.Feature("bar"))
+ bar = fea.get_feature("bar")
+ self.assertTrue(bar)
+ self.assertEquals(bar.get_ref(),"bar")
+ self.assertEquals(bar.namespace,"foo")
+ self.assertEquals(bar.fqr,"foo.bar")
+
+ def test_create_subfeature_and_get_namespace_with_config(self):
+ conf = api.Configuration("test.confml", namespace="com.nokia.s60")
+ conf.add_feature(api.Feature("foo"))
+ fea= conf.get_feature("foo")
+ fea.add_feature(api.Feature("bar"))
+ bar = fea.get_feature("bar")
+ self.assertTrue(bar)
+ self.assertEquals(bar.get_ref(),"bar")
+ self.assertEquals(bar.namespace,"com.nokia.s60.foo")
+ self.assertEquals(bar.fqr,"com.nokia.s60.foo.bar")
+
+ def test_create_feature_proxy(self):
+ fea= api.Feature("foo", name="foo bar")
+ feaproxy = api._FeatureProxy("foo",fea)
+ self.assertTrue(feaproxy.get_ref(),"foo")
+ self.assertEquals(feaproxy.namespace,"")
+ self.assertEquals(feaproxy.fqr,"foo")
+ self.assertEquals(feaproxy.name,"foo bar")
+ feaproxy.add_feature(api.Feature("bar", name="bar man"))
+ self.assertTrue(feaproxy.bar.get_ref(),"bar")
+ self.assertEquals(feaproxy.bar.namespace,"foo")
+ self.assertEquals(feaproxy.bar.fqr,"foo.bar")
+ self.assertEquals(feaproxy.bar.name,"bar man")
+
+
+ def test_create_feature_data(self):
+ dataobj = api.Data(ref="foo", value=132)
+ self.assertTrue(dataobj.fqr,"foo")
+ self.assertTrue(dataobj.get_value(),123)
+ self.assertTrue(dataobj.value,123)
+
+ def test_create_feature_data_proxy(self):
+ fea= api.Feature("foo")
+ feaproxy = api._FeatureDataProxy("foo",fea)
+ self.assertTrue(feaproxy.get_ref(),"foo")
+ self.assertEquals(feaproxy._get_data(),None)
+ self.assertEquals(feaproxy._get_value(),None)
+ feaproxy._add_data(api.Data(ref="foo", value=123))
+ self.assertEquals(feaproxy._get_data().get_value(),123)
+ feaproxy._add_data(api.Data(ref="foo", value=321))
+ self.assertEquals(feaproxy._get_data().get_value(),321)
+ self.assertEquals(feaproxy._get_datas()[0].get_value(),123)
+ self.assertEquals(feaproxy._get_datas()[1].get_value(),321)
+ self.assertEquals(feaproxy._get_values(),[123,321])
+
+ def test_access_feature_data_proxy_children_with_sequence_operations(self):
+ fea= api.Feature("foo")
+ feaproxy = api._FeatureDataProxy("foo",fea)
+ feaproxy.add_feature(api.Feature("child1"))
+ feaproxy.add_feature(api.Feature("child2"))
+ feaproxy.add_feature(api.Feature("?child"))
+ feaproxy.add_feature(api.Feature("child3"))
+ feaproxy.add_feature(api.Feature("child4"))
+ self.assertEquals(len(feaproxy),4)
+ self.assertEquals(feaproxy[0].get_ref(),'child1')
+ self.assertEquals(feaproxy[1].get_ref(),'child2')
+ self.assertEquals(feaproxy[2].get_ref(),'child3')
+ self.assertEquals(feaproxy[3].get_ref(),'child4')
+
+ del feaproxy[2]
+ self.assertEquals(len(feaproxy),3)
+ self.assertEquals(feaproxy[0].get_ref(),'child1')
+ self.assertEquals(feaproxy[1].get_ref(),'child2')
+ self.assertEquals(feaproxy[2].get_ref(),'child4')
+ self.assertEquals(feaproxy[2].get_ref(),'child4')
+ self.assertEquals(feaproxy.get_feature('?child').get_ref(),'?child')
+
+ def test_create_boolean_feature(self):
+ fea = api.Feature('test',type='boolean')
+ vset = fea.get_valueset()
+ self.assertTrue(vset <= api.ValueSet([True,False]))
+ self.assertTrue(len(vset) == 2)
+ self.assertTrue(True in vset)
+ self.assertTrue(False in vset)
+ self.assertFalse(123 in vset)
+
+ def test_create_string_feature(self):
+ fea = api.Feature('test',type='string')
+ vset = fea.get_valueset()
+ self.assertTrue('test' in vset)
+ self.assertTrue('foobar' in vset)
+ self.assertFalse(False in vset)
+ self.assertFalse(123 in vset)
+
+ def test_create_integer_feature(self):
+ fea = api.Feature('test',type='int')
+ vset = fea.get_valueset()
+ self.assertFalse('test' in vset)
+ self.assertFalse('foobar' in vset)
+ self.assertTrue(False in vset)
+ self.assertTrue(123 in vset)
+ self.assertTrue(0 in vset)
+ self.assertTrue(100000000 in vset)
+ self.assertFalse(-1 in vset)
+ self.assertFalse(0.2 in vset)
+
+ def test_create_selection_feature(self):
+ fea = api.Feature('test',type='selection')
+ fea.create_option('test', '1')
+ fea.create_option('one', '2')
+ fea.create_option('two', '3')
+ vset = fea.get_valueset()
+ self.assertTrue('1' in vset)
+ self.assertFalse('foo' in vset)
+ self.assertTrue('2' in vset)
+ self.assertTrue('3' in vset)
+ self.assertEquals(fea.get_option('value_2').get_name(), 'one')
+
+ def test_create_sequence_feature(self):
+ fea = api.FeatureSequence('test')
+ fea.add_feature(api.Feature('child1',type='int'))
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ self.assertEquals(fea.get_type(), 'sequence')
+ self.assertEquals(fea.list_features(), ['child1','child2','child3'])
+
+ def test_feature_get_dict(self):
+ fea= api.Feature("foo", type='int')
+ self.assertEquals(fea._dict(), {'ref': 'foo','type': 'int', 'name': 'foo'})
+
+ def test_clone_single_feature(self):
+ fea= api.Feature("foo", type='int')
+ fea2 = fea._clone()
+ self.comparefeatures(fea,fea2)
+
+ def test_clone_feature_with_subfeatures(self):
+ fea= api.Feature("foo")
+ fea.add_feature(api.Feature("child1",type='string'))
+ fea.add_feature(api.Feature("child2",type='int'))
+ fea.child1.add_feature(api.Feature("child12",type='int'))
+ fea2 = fea._clone()
+ self.comparefeatures(fea,fea2)
+ fea3 = fea._clone(recursion=True, recursion_depth=1)
+ self.comparefeatures(fea,fea3)
+ self.comparefeatures(fea.get_feature('child1'),fea3.get_feature('child1'))
+ self.comparefeatures(fea.get_feature('child2'),fea3.get_feature('child2'))
+ self.assertEquals(fea3.child1.list_features(),[])
+ fea4 = fea._clone(recursion=True)
+ self.comparefeatures(fea,fea4)
+ self.comparefeatures(fea.get_feature('child1'),fea4.get_feature('child1'))
+ self.comparefeatures(fea.get_feature('child2'),fea4.get_feature('child2'))
+ self.assertEquals(fea4.child1.list_features(),['child12'])
+ self.comparefeatures(fea.child1.get_feature('child12'),fea4.child1.get_feature('child12'))
+
+ def test_clone_feature_with_options(self):
+ fea= api.Feature("foo")
+ fea.add_feature(api.Feature("child1",type='selection'))
+ fea.add_feature(api.Feature("child2",type='int'))
+ fea.child1.create_option('one','1')
+ fea.child1.create_option('two','2')
+ fea.child1.create_option('three','3')
+ fea2 = fea._clone(recursion=True)
+ self.comparefeatures(fea,fea2)
+ self.comparefeatures(fea.get_feature('child1'),fea2.get_feature('child1'))
+ self.assertEquals(fea.child1.list_options(),fea2.child1.list_options())
+
+ def test_compare_features(self):
+ fea1= api.Feature("foo")
+ fea2= api.Feature("foo")
+ fea3= api.Feature("foo", type='boolean')
+ fea4= api.Feature("foo", bar='yes')
+ fea5= api.Feature("foo", bar='yes')
+ self.assertTrue(fea1._compare(fea2))
+ self.assertFalse(fea1._compare(fea3))
+ self.assertTrue(fea1._compare(fea4))
+ self.assertTrue(fea5._compare(fea4, ['bar']))
+ self.assertTrue(fea1._compare(fea2, ['bar']))
+
+class TestFeatureSequence(unittest.TestCase):
+ def comparefeatures(self,fea1,fea2):
+ self.assertEquals(fea1.ref, fea2.ref)
+ self.assertEquals(fea1.fqr, fea2.fqr)
+ self.assertEquals(fea1.name, fea2.name)
+ self.assertEquals(fea1.type, fea2.type)
+
+ # @test
+ def test_create_feature(self):
+ fea= api.FeatureSequence("foo")
+ self.assertTrue(fea)
+
+ def test_create_feature_with_children(self):
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ self.assertEquals(fea.list_features(),['child1','child2','child3'])
+
+ def test_create_configuration_with_sequence_and_get_default_view(self):
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ config = api.Configuration('foo.confml')
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ self.assertEquals(dview.list_all_features(),['foo','foo.child1','foo.child2','foo.child3'])
+
+ def test_create_configuration_with_sequence_and_add_data_with_default_view(self):
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ config = api.Configuration('foo.confml')
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ foofea = dview.get_feature('foo')
+
+ data = api.Data(ref='foo')
+ data._add(api.Data(ref='child1',value='test1'))
+ data._add(api.Data(ref='child2',value='test2'))
+ data._add(api.Data(ref='child3',value='test3'))
+ foofea.add_data(data)
+ data1 = api.Data(ref='foo', policy='append')
+ data1._add(api.Data(ref='child1',value='jee'))
+ data1._add(api.Data(ref='child2',value='oo'))
+ data1._add(api.Data(ref='child3',value='aa'))
+
+ foofea.add_data(data1)
+ self.assertEquals(len(foofea.get_data()), 2)
+
+ self.assertEquals(foofea.get_data()[0].list_features(), ['child1','child2','child3'])
+ self.assertEquals(foofea.get_data()[0].get_feature('child1').get_value(), 'test1')
+ self.assertEquals(foofea.get_data()[0].get_feature('child2').get_value(), 'test2')
+ self.assertEquals(foofea.get_data()[0].get_feature('child3').get_value(), 'test3')
+
+ self.assertEquals(foofea.get_data()[1].list_features(), ['child1','child2','child3'])
+ self.assertEquals(foofea.get_data()[1].get_feature('child1').get_value(), 'jee')
+ self.assertEquals(foofea.get_data()[1].get_feature('child2').get_value(), 'oo')
+ self.assertEquals(foofea.get_data()[1].get_feature('child3').get_value(), 'aa')
+
+ self.assertEquals(foofea.get_value(), [['test1','test2','test3'],
+ ['jee','oo','aa']])
+ self.assertEquals(foofea.get_data()[0][0].get_value(), 'test1')
+ # Test recurse
+ for row in foofea.get_data():
+ for col in row:
+ print col.get_value(),
+ print
+
+ def test_create_configuration_with_sequence_and_add_values_with_default_view(self):
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ config = api.Configuration('foo.confml')
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ foofea = dview.get_feature('foo')
+ # Test adding a data row with array
+ foofea.add_sequence(['1','2','3'])
+ foofea.add_sequence(['4','5','6'])
+ foofea.add_sequence(['7','8','9'])
+ print foofea.get_data()[0].get_feature('child1').get_value()
+ self.assertEquals(len(foofea.get_data()), 3)
+ self.assertEquals(foofea.get_value(), [['1','2','3'],
+ ['4','5','6'],
+ ['7','8','9']
+ ])
+
+
+ def test_create_configuration_with_sequence_and_add_sequence_value_directly(self):
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ config = api.Configuration('foo.confml')
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ foofea = dview.get_feature('foo')
+ # Test adding a data row with array
+ foofea.set_value([['1','2','3'],
+ ['4','5','6'],
+ ['7','8','9']
+ ])
+ self.assertEquals(len(foofea.get_data()), 3)
+ self.assertEquals(foofea.get_value(), [['1','2','3'],
+ ['4','5','6'],
+ ['7','8','9']
+ ])
+
+ def test_create_configuration_and_access_feature_value_with_property(self):
+ config = api.Configuration('foo.confml')
+ fea= api.Feature("foo")
+ config.add_feature(fea)
+ fea.set_value('test')
+ self.assertEquals(fea.value,'test')
+ dview = config.get_default_view()
+ feaproxy = dview.get_feature('foo')
+ val = feaproxy.value
+ self.assertEquals(val,'test')
+ feaproxy.value = 'test2'
+ self.assertEquals(feaproxy.value,'test2')
+ del feaproxy.value
+ self.assertEquals(feaproxy.value,None)
+ feaproxy.value = 'test3'
+ self.assertEquals(feaproxy.value,'test3')
+
+ def test_create_configuration_and_access_feature_type_with_property(self):
+ config = api.Configuration('foo.confml')
+ fea= api.Feature("foo", type='int')
+ config.add_feature(fea)
+ self.assertEquals(fea.type, 'int')
+ dview = config.get_default_view()
+ feaproxy = dview.get_feature('foo')
+ self.assertEquals(feaproxy.type, 'int')
+
+ def test_create_feature_seq_and_access_feature_value_with_property(self):
+ config = api.Configuration('foo.confml')
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child11'),'child1')
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ foofea = dview.get_feature('foo')
+ # Test adding a data row with array
+ foofea.set_value([[['1'],'2','3'],
+ [['4'],'5','6'],
+ [['7'],'8','9']
+ ])
+ self.assertEquals(foofea.value, [[['1'],'2','3'],
+ [['4'],'5','6'],
+ [['7'],'8','9']
+ ])
+
+ foofea.value = [[['1'],'2','3'],
+ [['7'],'8','9']
+ ]
+
+ self.assertEquals(foofea.data[0].value,[['1'],'2','3'])
+ self.assertEquals(foofea.data[1].value,[['7'],'8','9'])
+ self.assertEquals(foofea.data[1][1].value,'8')
+ self.assertEquals(foofea.get_value(), [[['1'],'2','3'],
+ [['7'],'8','9']
+ ])
+ self.assertEquals(foofea.child1.child11.value,['1','7'])
+ self.assertEquals(foofea.child1.value,[['1'],['7']])
+
+ def test_create_feature_seq_and_access_empty_data(self):
+ config = api.Configuration('foo.confml')
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child11'),'child1')
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ foofea = dview.get_feature('foo')
+ foofea.value = []
+ self.assertEquals(foofea.value, [])
+
+ def test_create_feature_seq_get_sequence_parent(self):
+ config = api.Configuration('foo.confml')
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child11'),'child1')
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ self.assertEquals(fea.child1.get_sequence_parent(), fea)
+ self.assertEquals(fea.child1.child11.get_sequence_parent(), fea)
+
+ def test_clone_feature_sequence(self):
+ fea= api.FeatureSequence("foo")
+ fea.add_feature(api.Feature('child1'))
+ fea.add_feature(api.Feature('child2'))
+ fea.add_feature(api.Feature('child3'))
+ fea2 = fea._clone(recursion=True)
+ self.comparefeatures(fea,fea2)
+ self.assertEquals(fea.list_features(),fea2.list_features())
+
+ def test_create_configuration_with_sequence_and_mapping_properties(self):
+ fea = api.FeatureSequence("SequenceSetting", mapKey='KeySubSetting', mapValue="ValueSubSetting")
+ fea.add_feature(api.Feature('KeySubSetting'))
+ fea.add_feature(api.Feature('ValueSubSetting'))
+
+ config = api.Configuration('foo.confml')
+ config.add_feature(fea)
+ dview = config.get_default_view()
+ seqfea = dview.get_feature("SequenceSetting")
+
+ self.assertEquals(seqfea.get_map_key().name,"KeySubSetting")
+ self.assertEquals(seqfea.get_map_value().name,"ValueSubSetting")
+ #add item 1
+ data = api.Data(ref='SequenceSetting')
+ data._add(api.Data(ref='KeySubSetting',value='Default'))
+ data._add(api.Data(ref='ValueSubSetting',value='Default value'))
+ seqfea.add_data(data)
+
+ #add item 2
+ data1 = api.Data(ref='SequenceSetting', policy='append')
+ data1._add(api.Data(ref='KeySubSetting',value='Key 1'))
+ data1._add(api.Data(ref='ValueSubSetting',value='Value 1'))
+ seqfea.add_data(data1)
+
+ self.assertEquals(len(seqfea.get_data()), 2)
+
+ self.assertEquals(seqfea.get_map_key_value('Default'),'Default value')
+ self.assertEquals(seqfea.get_map_key_value('Key 1'),'Value 1')
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_layer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_layer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,284 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public import api,exceptions,utils
+from cone.storage import stringstorage
+
+class TestLayer(unittest.TestCase):
+ storage_class = stringstorage.StringStorage
+
+ def test_create_layer(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ self.assertTrue(layer)
+
+# def test_create_layer_with_kwargs(self):
+# store = self.storage_class.open("temp/layertest.pk","w")
+# layer = api.Layer(store, "foo",confml_path="foobar", implml_path="")
+# self.assertTrue(layer)
+# self.assertEquals(layer.confml_folder.get_current_path(),"foo/foobar")
+# self.assertEquals(layer.implml_folder.get_current_path(),"foo")
+# layer = api.Layer(store, "foo",confml_path="f", implml_path="test", content_path="data", doc_path="foo")
+# self.assertEquals(layer.confml_folder.get_current_path(),"foo/f")
+# self.assertEquals(layer.implml_folder.get_current_path(),"foo/test")
+# self.assertEquals(layer.content_folder.get_current_path(),"foo/data")
+# self.assertEquals(layer.doc_folder.get_current_path(),"foo/foo")
+# layer = api.Layer(store, "foo")
+# self.assertEquals(layer.confml_folder.get_current_path(),"foo/confml")
+# self.assertEquals(layer.implml_folder.get_current_path(),"foo/implml")
+# self.assertEquals(layer.content_folder.get_current_path(),"foo/content")
+# self.assertEquals(layer.doc_folder.get_current_path(),"foo/doc")
+
+ def test_get_path(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ self.assertTrue(layer)
+ self.assertEquals(layer.get_current_path(),"foo")
+
+ def test_open_resource(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ self.assertTrue(layer)
+ res = layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_resources("", True),["confml/test.confml"])
+ self.assertEquals(store.list_resources("", True),["foo/confml/test.confml"])
+
+ def test_create_two_layers_and_open_resource(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ foo_layer = api.Layer(store, "foo")
+ bar_layer = api.Layer(store, "bar")
+ res = foo_layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = foo_layer.open_resource("root.confml","w")
+ res.close()
+ res = bar_layer.open_resource("confml/root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(foo_layer.list_resources("", True),['confml/test.confml', 'root.confml'])
+ self.assertEquals(store.list_resources("", True),['bar/confml/root.confml','foo/confml/test.confml','foo/root.confml'])
+ foo_layer.delete_resource("confml/test.confml")
+ self.assertEquals(foo_layer.list_resources("", True),["root.confml"])
+ self.assertEquals(store.list_resources("", True),["bar/confml/root.confml","foo/root.confml"])
+
+ def test_list_confml(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_confml(),['confml/foo.confml', 'confml/test.confml'])
+
+ def test_list_implml(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("implml/stuff/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_implml(),['implml/stuff/test.confml'])
+
+ def test_list_content(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("content/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("content/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_content(),['content/bar/test.txt', 'content/foo.confml'])
+
+ def test_list_doc(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("doc/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("doc/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_doc(),['doc/bar/test.txt', 'doc/foo.confml'])
+
+ def test_list_layer_resources(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("doc/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/bar.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("content/data/abc.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("foo.txt","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_all_resources(),['confml/bar.confml',
+ 'confml/foo.confml',
+ 'content/data/abc.txt',
+ 'doc/bar/test.txt'])
+
+ def test_list_layer_with_sublayer(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ layer = api.Layer(store, "foo", layers=[api.Layer(store, "bar")])
+ res = layer.open_resource("doc/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/bar.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("content/data/abc.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("foo.txt","w")
+ res.write("foo.conf")
+ res.close()
+ barlayer = layer.get_layer('bar')
+ res = barlayer.open_resource("content/barcode.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = barlayer.open_resource("confml/hooo.confml","w")
+ res.write("foo.conf")
+ res.close()
+
+ self.assertEquals(layer.list_all_resources(),['confml/bar.confml',
+ 'confml/foo.confml',
+ 'content/data/abc.txt',
+ 'doc/bar/test.txt',
+ 'bar/confml/hooo.confml',
+ 'bar/content/barcode.txt'])
+
+ self.assertEquals(layer.list_implml(),[])
+ self.assertEquals(layer.list_confml(),['confml/bar.confml',
+ 'confml/foo.confml',
+ 'bar/confml/hooo.confml'])
+ self.assertEquals(layer.list_content(),['content/data/abc.txt', 'bar/content/barcode.txt'])
+ self.assertEquals(layer.list_doc(),['doc/bar/test.txt'])
+
+class TestCompositeLayer(unittest.TestCase):
+ storage_class = stringstorage.StringStorage
+
+ def test_create_compositelayer(self):
+ store = self.storage_class.open("temp/layertestcomposite.pk","w")
+ clayer = api.CompositeLayer()
+ self.assertTrue(clayer)
+
+ def test_create_with_layer(self):
+ store = self.storage_class.open("temp/layertestcomposite.pk","w")
+ clayer = api.CompositeLayer("sub",layers=[api.Layer(store,"test"), api.Layer(store,"foo/bar")])
+ self.assertEquals(clayer.list_layers(),['test', 'foo/bar'])
+
+ def test_create_with_layer_and_add(self):
+ store = self.storage_class.open("temp/layertestcomposite.pk","w")
+ clayer = api.CompositeLayer(layers=[api.Layer(store,"test"), api.Layer(store,"foo/bar")])
+ self.assertEquals(clayer.list_layers(),['test', 'foo/bar'])
+ clayer.add_layer(api.Layer(store,"res"))
+ self.assertEquals(clayer.list_layers(),['test', 'foo/bar', 'res'])
+
+ def test_get_layer(self):
+ store = self.storage_class.open("temp/layertestcomposite.pk","w")
+ clayer = api.CompositeLayer(layers=[api.Layer(store,"test"), api.Layer(store,"foo/bar")])
+ self.assertEquals(clayer.list_layers(),['test', 'foo/bar'])
+ layer = clayer.get_layer('foo/bar')
+ self.assertEquals(layer.get_current_path(),'foo/bar')
+
+ def test_create_layers_with_resources_and_list_with_composite(self):
+ store = self.storage_class.open("temp/layertest.pk","w")
+ foolayer = api.Layer(store, "foo")
+ res = foolayer.open_resource("doc/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = foolayer.open_resource("implml/foo2.crml","w")
+ res.write("foo.conf")
+ res.close()
+ res = foolayer.open_resource("confml/bar.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = foolayer.open_resource("content/data/abc.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = foolayer.open_resource("foo.txt","w")
+ res.write("foo.conf")
+ res.close()
+ barlayer = api.Layer(store, "bar")
+ res = barlayer.open_resource("doc/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = barlayer.open_resource("implml/foo.crml","w")
+ res.write("foo.conf")
+ res.close()
+ res = barlayer.open_resource("confml/bar.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = barlayer.open_resource("content/data/abc.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = barlayer.open_resource("foo.txt","w")
+ res.write("foo.conf")
+ res.close()
+ clayer = api.CompositeLayer('test',layers=[foolayer,barlayer])
+
+ self.assertEquals(clayer.list_all_resources(),['foo/confml/bar.confml',
+ 'foo/content/data/abc.txt',
+ 'foo/doc/bar/test.txt',
+ 'foo/implml/foo2.crml',
+ 'bar/confml/bar.confml',
+ 'bar/content/data/abc.txt',
+ 'bar/doc/bar/test.txt',
+ 'bar/implml/foo.crml',])
+ self.assertEquals(clayer.list_implml(),['foo/implml/foo2.crml','bar/implml/foo.crml'])
+ self.assertEquals(clayer.list_confml(),['foo/confml/bar.confml', 'bar/confml/bar.confml'])
+ self.assertEquals(clayer.list_content(),['foo/content/data/abc.txt', 'bar/content/data/abc.txt'])
+ self.assertEquals(clayer.list_doc(),['foo/doc/bar/test.txt', 'bar/doc/bar/test.txt'])
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_mapping.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_mapping.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import unittest
+import string
+import sys
+import os
+import shutil
+import __init__
+
+from cone.public import api, exceptions, mapping
+
+class TestMapping(unittest.TestCase):
+ def test_get_mapper(self):
+ mapper = api.get_mapper('confml')
+ self.assertTrue(isinstance(mapper, mapping.BaseMapper))
+
+ def test_map_feature(self):
+ fea = api.Feature("test")
+ mapper = fea._get_mapper('confml')
+ fea2 = mapper.map_object(fea)
+ self.assertEquals(fea,fea2)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_options.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_options.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,104 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test sets
+"""
+import unittest
+import sets
+import sys
+import os
+import __init__
+
+from cone.public import api,exceptions,utils
+
+
+class TestOption(unittest.TestCase):
+ def test_create_option(self):
+ elem = api.Option('test','123')
+ self.assertTrue(elem)
+ self.assertTrue(elem.get_name(),'test')
+ self.assertTrue(elem.get_value(),'123')
+
+ def test_add_option(self):
+ fea = api.Feature('test')
+ fea.add_option(api.Option('foo','1'))
+ fea.add_option(api.Option('test','2'))
+ self.assertEquals(fea.list_options(), ['value_1','value_2'])
+
+ def test_add_option_invalid_param(self):
+ fea = api.Feature('test')
+ self.assertRaises(TypeError, fea.add_option, object())
+
+ def test_option_compare(self):
+ elem1 = api.Option('test','1')
+ elem2 = api.Option('foo','2')
+ elem3 = api.Option('test','3')
+ self.assertFalse(elem1==elem2)
+ self.assertFalse(elem1==elem3)
+ self.assertTrue(elem1=='opt_value_1')
+ self.assertTrue(elem2=='opt_value_2')
+ self.assertTrue('opt_value_2' == elem2)
+
+ def test_create_feature_with_options(self):
+ fea = api.Feature('test')
+ fea.create_option('foo','3')
+ fea.create_option('test','4')
+ self.assertEquals(fea.list_options(), ['value_3','value_4'])
+ self.assertEquals(fea.opt_value_3.get_name(),'foo')
+ self.assertEquals(fea.opt_value_3.get_value(),'3')
+ self.assertEquals(fea.opt_value_4.get_name(),'test')
+ self.assertEquals(fea.opt_value_4.get_value(),'4')
+
+ def test_list_and_get_options(self):
+ fea = api.Feature('test')
+ fea.create_option('foo','1')
+ fea.create_option('test','2')
+ fea.create_option('bar','3')
+
+ self.assertEquals(fea.list_options(), ['value_1', 'value_2', 'value_3'])
+
+ self.assertEquals(fea.get_option('value_1').get_name(), 'foo')
+ self.assertEquals(fea.get_option('value_2').get_name(), 'test')
+ self.assertEquals(fea.get_option('value_3').get_name(), 'bar')
+
+ def test_get_option_nonexistent(self):
+ fea = api.Feature('test')
+ self.assertRaises(exceptions.NotFound, fea.get_option, 'foo')
+
+ def test_get_option_invalid_type(self):
+ fea = api.Feature('test')
+ fea.add(api.Feature('opt_foo'))
+ self.assertRaises(TypeError, fea.get_option, 'foo')
+
+ def test_remove_option(self):
+ fea = api.Feature('test')
+ fea.create_option('foo','1')
+ fea.create_option('test','2')
+ fea.create_option('bar','3')
+ self.assertEquals(fea.list_options(), ['value_1', 'value_2', 'value_3'])
+
+ fea.remove_option('value_2')
+ self.assertEquals(fea.list_options(), ['value_1', 'value_3'])
+
+ def test_remove_option_nonexistent(self):
+ fea = api.Feature('test')
+ self.assertRaises(exceptions.NotFound, fea.remove_option, 'xyz')
+
+ def test_remove_option_invalid_param(self):
+ fea = api.Feature('test')
+ fea.add(api.Feature('opt_xyz'))
+ self.assertRaises(TypeError, fea.remove_option, 'xyz')
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_persistence.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_persistence.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public import persistence, exceptions
+
+class ConeDummyReader(persistence.ConeReader):
+
+ @classmethod
+ def supported_elem(cls, elemname):
+ if elemname.lower() == "dum":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ super(persistence.ConeReader,self).__init__()
+
+
+class ConeDummyWriter(persistence.ConeWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ if classname.lower() == "dum":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ super(persistence.ConeWriter,self).__init__()
+
+
+class TestFactory(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ # @test
+ def test_get_reader_fails(self):
+ try:
+ persistence.PersistenceFactory.get_reader_for_elem("")
+ self.fail("Not existing reader creation succeeds?")
+ except exceptions.ConePersistenceError,e:
+ self.assertTrue(True)
+
+ def test_get_writer_fails(self):
+ try:
+ persistence.PersistenceFactory.get_writer_for_class("")
+ self.fail("Not existing writer creation succeeds?")
+ except exceptions.ConePersistenceError,e:
+ self.assertTrue(True)
+
+ def test_get_reader_ok(self):
+ r = persistence.PersistenceFactory.get_reader_for_elem("Dum")
+ self.assertTrue(isinstance(r,ConeDummyReader))
+
+ def test_get_reader_low(self):
+ r = persistence.PersistenceFactory.get_reader_for_elem("dum")
+ self.assertTrue(isinstance(r,ConeDummyReader))
+
+ def test_get_reader_upper(self):
+ r = persistence.PersistenceFactory.get_reader_for_elem("DUM")
+ self.assertTrue(isinstance(r,ConeDummyReader))
+
+ def test_get_writer_ok(self):
+ r = persistence.PersistenceFactory.get_writer_for_class("Dum")
+ self.assertTrue(isinstance(r,ConeDummyWriter))
+
+ def test_get_writer_ok_low(self):
+ r = persistence.PersistenceFactory.get_writer_for_class("dum")
+ self.assertTrue(isinstance(r,ConeDummyWriter))
+
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_plugin_api.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_plugin_api.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1081 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os
+import logging
+import __init__
+from cone.public import *
+from cone.public import _plugin_reader
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+Tfd = _plugin_reader.TempVariableDefinition
+Tsfd = _plugin_reader.TempVariableSequenceDefinition
+Sro = _plugin_reader.SettingRefsOverride
+
+
+
+MULTI_IMPL_1 = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+""".encode('utf-8')
+
+MULTI_IMPL_2 = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+""".encode('utf-8')
+
+MULTI_IMPL_3 = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+""".encode('utf-8')
+
+UNSUPPORTED_IMPL_1 = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+""".encode('utf-8')
+
+UNSUPPORTED_IMPL_2 = """
+
+
+
+
+
+
+
+
+
+""".encode('utf-8')
+
+SINGLE_IMPL_1 = """
+
+
+
+
+
+""".encode('utf-8')
+
+SINGLE_IMPL_2 = """
+
+""".encode('utf-8')
+
+SINGLE_IMPL_3 = """
+
+
+
+""".encode('utf-8')
+
+IGNORED_NAMESPACE_IMPL_1 = """
+
+
+
+
+
+
+
+
+
+""".encode('utf-8')
+
+IGNORED_NAMESPACE_IMPL_2 = """
+
+
+
+
+""".encode('utf-8')
+
+NO_IMPL = """
+
+
+""".encode('utf-8')
+
+class Mock(object):
+ pass
+
+class MockView(object):
+ def __init__(self, feature_dict):
+ self.feature_dict = feature_dict
+
+ def get_feature(self, ref):
+ feature = Mock()
+ feature.get_value = lambda: self.feature_dict[ref]
+ feature.get_original_value = lambda: self.feature_dict[ref]
+ return feature
+
+class MockConfiguration(object):
+ def __init__(self, resources, features={}):
+ self.resources = resources
+ self.features = features
+
+ def get_resource(self, ref):
+ res = Mock()
+ res.read = lambda: self.resources[ref]
+ res.close = lambda: None
+ return res
+
+ def get_layer(self):
+ layer = Mock()
+ layer.list_implml = lambda: self.resources.keys()
+ return layer
+
+ def get_doc(self, ref):
+ return utils.etree.fromstring(self.get_resource(ref).read())
+
+ def get_default_view(self):
+ return MockView(self.features)
+
+class MockImpl(plugin.ImplBase):
+ def __init__(self, data):
+ self.data = data
+ self.generate_invoked = False
+
+ @classmethod
+ def create(cls, resource_ref, configuration, data):
+ impl = cls(data)
+ plugin.ImplBase.__init__(impl, resource_ref, configuration)
+ return impl
+
+ def generate(self, context=None):
+ if context and hasattr(context,'objects'):
+ context.objects.append(self)
+ self.generate_invoked = True
+
+ def __repr__(self):
+ return "MockImpl(%r)" % self.data
+
+ def __eq__(self, other):
+ if type(self) == type(other):
+ return self.data == other.data
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __lt__(self, other):
+ if type(self) == type(other):
+ return self.data < other.data
+ else:
+ return False
+
+class MockReaderBase(plugin.ReaderBase):
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, root_elem):
+ data = [cls.__name__, resource_ref]
+ for elem in root_elem.findall('{%s}elem' % cls.NAMESPACE):
+ data.append(elem.attrib)
+ return MockImpl.create(resource_ref, configuration, data)
+
+class MockReader1(MockReaderBase):
+ NAMESPACE = "http://www.test.com/xml/1"
+ FILE_EXTENSIONS = ['mock1ml']
+class MockReader2(MockReaderBase):
+ NAMESPACE = "http://www.test.com/xml/2"
+ FILE_EXTENSIONS = ['mock2ml']
+class MockReader3(MockReaderBase):
+ NAMESPACE = "http://www.test.com/xml/3"
+ IGNORED_NAMESPACES = ["http://www.test.com/xml/ignored/3"]
+ FILE_EXTENSIONS = ['mock3ml', 'test3ml']
+
+MOCK_READER_CLASSES = [MockReader1, MockReader2, MockReader3]
+
+mock_config = MockConfiguration({
+ 'layer1/implml/multi1.implml' : MULTI_IMPL_1,
+ 'layer1/implml/multi2.implml' : MULTI_IMPL_2,
+ 'layer1/implml/multi3.implml' : MULTI_IMPL_3,
+ 'layer1/implml/unsupported1.implml' : UNSUPPORTED_IMPL_1,
+ 'layer1/implml/unsupported2.implml' : UNSUPPORTED_IMPL_2,
+ 'layer1/implml/single1.implml' : SINGLE_IMPL_1,
+ 'layer1/implml/single2.implml' : SINGLE_IMPL_2,
+ 'layer1/implml/single3.implml' : SINGLE_IMPL_3,
+ 'layer1/implml/none.implml' : NO_IMPL,
+ 'layer1/implml/broken.implml' : 'Some invalid XML data...',
+ 'layer1/implml/single1.mock1ml' : SINGLE_IMPL_1,
+ 'layer1/implml/single2.mock2ml' : SINGLE_IMPL_2,
+ 'layer1/implml/single3.mock3ml' : SINGLE_IMPL_3,
+ 'layer1/implml/single3.test3ml' : SINGLE_IMPL_3,
+ 'layer1/implml/ignored_ns_1.mock3ml' : IGNORED_NAMESPACE_IMPL_1,
+ 'layer1/implml/ignored_ns_2.mock3ml' : IGNORED_NAMESPACE_IMPL_2,
+ 'layer1/implml/multi1.dummyml' : MULTI_IMPL_1,
+ 'layer1/implml/dummy' : MULTI_IMPL_1,
+})
+
+class TestPluginImplBase(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_implbase_add_tags(self):
+ impl = plugin.ImplBase('test',None)
+ impl.set_tags({'target': ['test', 'foo']})
+ self.assertEquals(impl.get_tags()['target'],['test','foo'])
+ #self.assertEquals(impl.has_tag({}, policy='OR'), True)
+ self.assertEquals(impl.has_tag({'target': ['test']}, policy='OR'), True)
+ self.assertEquals(impl.has_tag({'target': ['test']}, policy='AND'), True)
+ self.assertEquals(impl.has_tag({'target': ['foo']}, policy='OR'), True)
+ self.assertEquals(impl.has_tag({'target': ['foo']}, policy='AND'), True)
+ self.assertEquals(impl.has_tag({'target': ['test','foo']}, policy='OR'), True)
+ self.assertEquals(impl.has_tag({'target': ['test','foo']}, policy='AND'), True)
+ self.assertEquals(impl.has_tag({'target': ['test2','foo']}, policy='OR'), True)
+ self.assertEquals(impl.has_tag({'target': ['test2','foo']}, policy='AND'), False)
+ self.assertEquals(impl.has_tag({'foo': ['foo']}, policy='OR'), False)
+ self.assertEquals(impl.has_tag({'foo': ['foo']}, policy='AND'), False)
+ self.assertEquals(impl.has_tag({'target': ['foo'], 'foo':['bar']}, policy='AND'), False)
+ self.assertEquals(impl.has_tag({'target': ['foo'], 'foo':['bar']}, policy='OR'), True)
+
+ def test_implbase_tags_with_refs(self):
+ config = MockConfiguration({}, features = {
+ 'Foo.Bar' : 'foobar',
+ 'Foo.Baz' : 'foobaz',
+ 'Feature.TagName' : 'tagname',
+ 'Feature.TagValue' : 'tagvalue',
+ })
+
+ impl = plugin.ImplBase('test', config)
+ impl.set_tags({
+ 'test' : ['${Foo.Bar}', 'foo', 'bar', '${Foo.Bar} and ${Foo.Baz}'],
+ '${Feature.TagName}': ['${Feature.TagValue}']})
+
+ expected = {
+ 'test': ['foobar', 'foo', 'bar', 'foobar and foobaz'],
+ 'tagname': ['tagvalue'],
+ }
+ self.assertEquals(impl.get_tags(), expected)
+
+ def test_has_ref(self):
+ impl = plugin.ImplBase('test', None)
+ self.assertEquals(impl.has_ref('Foo.Bar'), None)
+
+ impl.get_refs = lambda: ['Foo.Bar', 'Xyz']
+
+ # Test using different supported parameter types
+ self.assertTrue(impl.has_ref('Foo.Bar'))
+ self.assertTrue(impl.has_ref(['Foo.Bar']))
+ self.assertTrue(impl.has_ref(('Foo.Bar',)))
+
+ # Impl uses the exact given ref
+ self.assertTrue(impl.has_ref('Foo.Bar'))
+ self.assertTrue(impl.has_ref('Xyz'))
+
+ # Impl uses the given ref's parent ref
+ self.assertTrue(impl.has_ref('Foo.Bar.Baz'))
+ self.assertTrue(impl.has_ref('Xyz.Zyx'))
+
+ # Impl does not use the entire parent ref of 'Foo.Bar', only the
+ # 'Bar' sub-ref
+ self.assertFalse(impl.has_ref('Foo'))
+
+ # Various refs almost matching a specified ref
+ self.assertFalse(impl.has_ref('Fo'))
+ self.assertFalse(impl.has_ref('Fog'))
+ self.assertFalse(impl.has_ref('Food'))
+ self.assertFalse(impl.has_ref('Foo.Ba'))
+ self.assertFalse(impl.has_ref('Foo.Bag'))
+ self.assertFalse(impl.has_ref('Foo.Bard'))
+
+ # Various refs not at all in the impl's ref list
+ self.assertFalse(impl.has_ref('Yay'))
+ self.assertFalse(impl.has_ref(['Yay', 'Fhtagn']))
+
+ # One of the refs in the given list matches
+ self.assertTrue(impl.has_ref(['Yay', 'Fhtagn', 'Foo.Bar']))
+ self.assertTrue(impl.has_ref(['Yay', 'Foo.Bar.Baz', 'Fhtagn']))
+ self.assertTrue(impl.has_ref(['Yay', 'Xyz', 'Fhtagn']))
+
+ def test_impl_container_eval_context_with_tags(self):
+ container = plugin.ImplBase("norm", None)
+ context = plugin.GenerationContext()
+ self.assertTrue(container._eval_context(context))
+ container.set_tags({'target':['rofs2','core']})
+ context.tags = {'target': ['rofs2'], 'foobar': ['test']}
+ self.assertTrue(container._eval_context(context))
+ context.tags_policy = "AND"
+ self.assertFalse(container._eval_context(context))
+ container.set_tags({})
+ self.assertFalse(container._eval_context(context))
+ context.tags = {'target': ['rofs2']}
+ self.assertFalse(container._eval_context(context))
+ context.tags = {}
+ self.assertTrue(container._eval_context(context))
+
+class TestPluginImplSet(unittest.TestCase):
+
+ def test_add_implementation_and_list(self):
+ container = plugin.ImplSet()
+ imp1 = plugin.ImplBase("implml/test.content",None)
+ imp2a = plugin.ImplBase("implml/copy.content",None)
+ imp2b = plugin.ImplBase("implml/copy.content",None)
+ container.add_implementation(imp1)
+ container.add_implementation(imp2a)
+ container.add_implementation(imp2b)
+ self.assertEquals(sorted(container.list_implementation()),
+ sorted(['implml/test.content',
+ 'implml/copy.content']))
+
+ def test_add_implementation_and_get_implementations_by_file(self):
+ container = plugin.ImplSet()
+ imp1 = plugin.ImplBase("implml/test.content",None)
+ imp2a = plugin.ImplBase("implml/copy.content",None)
+ imp2b = plugin.ImplBase("implml/copy.content",None)
+ container.add_implementation(imp1)
+ container.add_implementation(imp2a)
+ container.add_implementation(imp2b)
+ self.assertEquals(container.get_implementations_by_file("implml/test.content"), [imp1])
+ self.assertEquals(sorted(container.get_implementations_by_file("implml/copy.content")),
+ sorted([imp2a, imp2b]))
+
+ def test_add_implementation_and_remove_implementation(self):
+ container = plugin.ImplSet()
+ imp1 = plugin.ImplBase("implml/test.content",None)
+ imp2a = plugin.ImplBase("implml/copy.content",None)
+ imp2b = plugin.ImplBase("implml/copy.content",None)
+ container.add_implementation(imp1)
+ container.add_implementation(imp2a)
+ container.add_implementation(imp2b)
+ container.remove_implementation("implml/test.content")
+ self.assertEquals(len(container.list_implementation()),1)
+ self.assertEquals(container.list_implementation()[0],"implml/copy.content")
+
+ def test_add_implementation_and_remove_all(self):
+ container = plugin.ImplSet()
+ imp1 = plugin.ImplBase("implml/test.content",None)
+ imp2a = plugin.ImplBase("implml/copy.content",None)
+ imp2b = plugin.ImplBase("implml/copy.content",None)
+ imp3 = plugin.ImplBase("implml/foo.content",None)
+ container.add_implementation(imp1)
+ container.add_implementation(imp2a)
+ container.add_implementation(imp2b)
+ container.add_implementation(imp3)
+ for implref in container.list_implementation():
+ container.remove_implementation(implref)
+ self.assertEquals(len(container.list_implementation()),0)
+
+ def test_create_impl_set(self):
+ plugin.create_impl_set('',None);
+ pass
+
+ def test_add_implementation_find_with_tags(self):
+ class TestPlugin(plugin.ImplBase):
+ pass
+ container = plugin.ImplSet()
+ imp1 = TestPlugin("implml/test.content",None)
+ imp2 = TestPlugin("implml/copy.content",None)
+ imp3 = TestPlugin("implml/foo.content",None)
+ imp1.set_tags({'target': ['core','rofs2','rofs3']})
+ imp2.set_tags({'target': ['rofs3','uda']})
+ imp3.set_tags({'target': ['mmc','uda']})
+ container.add_implementation(imp1)
+ container.add_implementation(imp2)
+ container.add_implementation(imp3)
+ self.assertEquals(list(container.filter_implementations(tags={'target' : ['rofs3']})),
+ [imp1,imp2])
+ self.assertEquals(list(container.filter_implementations(tags={'target' : ['uda']})),
+ [imp2,imp3])
+ self.assertEquals(list(container.filter_implementations(tags={'target' : ['mmc','uda']}, policy='AND')),
+ [imp3])
+ self.assertEquals(list(container.filter_implementations(tags={'target' : ['mmc','uda']}, policy='OR')),
+ [imp2, imp3])
+ cont = container.filter_implementations(tags={'target' : ['core']}) | container.filter_implementations(tags={'target' : ['mmc']})
+ self.assertEquals(len(cont),2)
+ self.assertEquals(list(cont), [imp1,imp3])
+
+ cont = container.filter_implementations(tags={'target' : ['rofs3']}) & container.filter_implementations(tags={'target' : ['uda']})
+ self.assertEquals(len(cont),1)
+ self.assertEquals(list(cont), [imp2])
+
+ def test_pre_impl_filter(self):
+ resources = [
+ "foo.txt",
+ ".hidden_file",
+ ".test/test.txt",
+ "layer1/implml/.hidden",
+ "layer1/implml/test.crml",
+ "layer1/implml/test3.gcfml",
+ "layer1/implml/.svn/text-base/test.crml.svn-base",
+ "layer1/implml/subdir/test5.crml",
+ "layer1/implml/subdir/test6.ruleml",
+ "layer1/implml/subdir/.scripts/test6_ruleml.py",
+ ]
+
+ expected = [
+ "foo.txt",
+ "layer1/implml/test.crml",
+ "layer1/implml/test3.gcfml",
+ "layer1/implml/subdir/test5.crml",
+ "layer1/implml/subdir/test6.ruleml",
+ ]
+
+ self.assertEquals(expected, plugin.pre_filter_impls(resources))
+
+ # Test with backslashes
+ resources = map(lambda path: path.replace('/', '\\'), resources)
+ expected = map(lambda path: path.replace('/', '\\'), expected)
+ self.assertEquals(expected, plugin.pre_filter_impls(resources))
+
+
+class TestPluginImplSetCopy(unittest.TestCase):
+ class TestImpl(plugin.ImplBase):
+ pass # No default invocation phase specified, should be 'normal'
+ class PreImpl(plugin.ImplBase):
+ DEFAULT_INVOCATION_PHASE = 'pre'
+ class NormalImpl(plugin.ImplBase):
+ DEFAULT_INVOCATION_PHASE = 'normal'
+ class PostImpl(plugin.ImplBase):
+ DEFAULT_INVOCATION_PHASE = 'post'
+
+ def setUp(self):
+ plugin.ImplFactory.set_reader_classes_override(MOCK_READER_CLASSES)
+
+ def tearDown(self):
+ plugin.ImplFactory.set_reader_classes_override(None)
+
+ def _get_impl_container(self):
+ impl_files = ['layer1/implml/single1.implml',
+ 'layer1/implml/single2.implml',
+ 'layer1/implml/single3.implml',
+ 'layer1/implml/multi1.implml',
+ 'layer1/implml/multi2.implml']
+ return plugin.create_impl_set(impl_files, mock_config)
+
+
+ def test_get_test_impl_container(self):
+ container = self._get_impl_container()
+ # There are 5 ImplML files
+ self.assertEquals(len(container.list_implementation()), 5)
+ # ...but two of them contain 3 implementations each
+ self.assertEquals(len(container), 5)
+
+ def _get_phase_test_impl_container(self):
+ return plugin.ImplSet([
+ self.TestImpl('foo.test', None),
+ self.NormalImpl('foo.norm', None),
+ self.PreImpl('foo.pre', None),
+ self.PostImpl('test.post', None),
+ self.PostImpl('foo.post', None),
+ ])
+
+ def test_get_phase_test_impl_container(self):
+ container = self._get_phase_test_impl_container()
+ self.assertEquals(5, len(container))
+ self.assertEquals(len(container.list_implementation()), 5)
+
+ def check(filename, phase):
+ impls = container.get_implementations_by_file(filename)
+ self.assertEquals(1, len(impls))
+ impl = impls[0]
+ self.assertEquals(impl.ref, filename)
+ self.assertEquals(impl.invocation_phase(), phase)
+ check('foo.test', 'normal')
+ check('foo.norm', 'normal')
+ check('foo.pre', 'pre')
+ check('test.post', 'post')
+ check('foo.post', 'post')
+
+ return container
+
+ def test_create_impl_set(self):
+ container = self._get_impl_container()
+ # There are 5 ImplML files
+ self.assertEquals(len(container.list_implementation()), 5)
+ # ...but two of them contain 3 implementations each
+ self.assertEquals(len(container), 5)
+
+ def test_invocation_phases(self):
+ container = self._get_phase_test_impl_container()
+ phases = container.invocation_phases()
+ self.assertEquals(phases,['pre','normal','post'])
+
+ def test_copy(self):
+ container = self._get_impl_container()
+ newcontainer = container.copy()
+ self.assertTrue(newcontainer is not container)
+ self.assertEquals(len(newcontainer), 5)
+
+ def test_execute_generate(self):
+ container = self._get_impl_container()
+ container.execute(container, 'generate')
+ actual_impls = []
+ for impl in container:
+ if isinstance(impl, plugin.ImplContainer):
+ actual_impls += impl.get_all_implementations()
+ else:
+ actual_impls.append(impl)
+ for impl in actual_impls:
+ self.assertTrue(impl.generate_invoked)
+
+ def test_impl_container_generate(self):
+ container = self._get_impl_container()
+ context = plugin.GenerationContext()
+ context.history = ""
+ context.objects = []
+ container.generate(context)
+ self.assertEquals(len(context.objects), 9)
+ actual_impls = []
+ for impl in container:
+ if isinstance(impl, plugin.ImplContainer):
+ actual_impls += impl.get_all_implementations()
+ else:
+ actual_impls.append(impl)
+ for impl in actual_impls:
+ self.assertTrue(impl.generate_invoked)
+
+ def test_filter_all(self):
+ container = self._get_impl_container()
+ impl_list = container.filter_implementations()
+ self.assertEquals(len(impl_list), 5)
+
+ def test_filter_for_pre_phase(self):
+ container = self._get_phase_test_impl_container()
+ impl_list = list(container.filter_implementations(phase='pre'))
+ self.assertEquals(len(impl_list), 1)
+ self.assertEquals(impl_list[0].invocation_phase(), 'pre')
+ self.assertEquals(impl_list[0].ref, 'foo.pre')
+
+ def test_filter_for_normal_phase(self):
+ container = self._get_phase_test_impl_container()
+ impl_list = list(container.filter_implementations(phase='normal'))
+ self.assertEquals(len(impl_list), 2)
+ self.assertEquals(impl_list[0].invocation_phase(), 'normal')
+ self.assertEquals(impl_list[1].invocation_phase(), 'normal')
+
+ def test_filter_for_post_phase(self):
+ container = self._get_phase_test_impl_container()
+ impl_list = list(container.filter_implementations(phase='post'))
+ self.assertEquals(len(impl_list), 2)
+ self.assertEquals(impl_list[0].invocation_phase(), 'post')
+ self.assertEquals(impl_list[1].invocation_phase(), 'post')
+
+
+class TestPluginImplSettings(unittest.TestCase):
+ class Test1Impl(plugin.ImplBase):
+ IMPL_TYPE_ID = "test1"
+ class Test2Impl(plugin.ImplBase):
+ IMPL_TYPE_ID = "test2"
+ class Test3Impl(plugin.ImplBase):
+ IMPL_TYPE_ID = "test3"
+
+ def test_plugin_settings(self):
+ settings.SettingsFactory.cone_parser().read([os.path.join(ROOT_PATH,'test_defaults.cfg')])
+ impl = TestPluginImplSettings.Test1Impl("",None)
+ self.assertEquals(impl.output_root, 'output')
+ self.assertEquals(impl.output_subdir, '')
+ impl.output_subdir = 'foobar'
+ self.assertEquals(impl.get_tags(), {})
+ self.assertEquals(impl.output, 'output/foobar')
+
+ impl = TestPluginImplSettings.Test2Impl("",None)
+ self.assertEquals(impl.output_subdir, '')
+
+
+
+class TestReaders(unittest.TestCase):
+
+ def setUp(self):
+ plugin.ImplFactory.set_reader_classes_override(MOCK_READER_CLASSES)
+
+ def tearDown(self):
+ plugin.ImplFactory.set_reader_classes_override(None)
+
+ def assert_namespace_list_equals(self, resource_ref, expected_namespaces):
+ self.assertEquals(
+ expected_namespaces,
+ _plugin_reader.ImplReader._get_namespaces(mock_config.get_doc(resource_ref)))
+
+ def test_get_needed_reader_classes(self):
+ self.assert_namespace_list_equals('layer1/implml/none.implml', [])
+
+ self.assert_namespace_list_equals('layer1/implml/single1.implml',
+ ['http://www.test.com/xml/1'])
+
+ self.assert_namespace_list_equals('layer1/implml/single2.implml',
+ ['http://www.test.com/xml/2'])
+
+ self.assert_namespace_list_equals('layer1/implml/multi1.implml',
+ ['http://www.symbianfoundation.org/xml/implml/1',
+ 'http://www.test.com/xml/1',
+ 'http://www.test.com/xml/2',
+ 'http://www.test.com/xml/3'])
+
+ self.assert_namespace_list_equals('layer1/implml/multi2.implml',
+ ['http://www.symbianfoundation.org/xml/implml/1',
+ 'http://www.test.com/xml/1',
+ 'http://www.test.com/xml/2',
+ 'http://www.test.com/xml/3'])
+
+ self.assert_namespace_list_equals('layer1/implml/multi3.implml',
+ ['http://www.symbianfoundation.org/xml/implml/1',
+ 'http://www.test.com/xml/1',
+ 'http://www.test.com/xml/2'])
+
+ self.assert_namespace_list_equals('layer1/implml/unsupported1.implml',
+ ['http://www.test.com/xml/1',
+ 'http://www.test.com/xml/2',
+ 'http://www.test.com/xml/4'])
+
+ self.assert_namespace_list_equals('layer1/implml/unsupported2.implml',
+ ['http://www.test.com/xml/6',
+ 'http://www.test.com/xml/2',
+ 'http://www.test.com/xml/4'])
+
+ def assert_read_impls_equal(self, expected, resource_ref):
+ actual = plugin.ImplFactory.get_impls_from_file(resource_ref, mock_config)
+ if len(actual) == 1 and isinstance(actual[0], plugin.ImplContainer):
+ actual = actual[0].get_all_implementations()
+ self.assertEquals(expected, actual)
+
+# # Assert that the implementations have the correct impl indices set
+# for i, impl in enumerate(actual):
+# self.assertEquals(i, impl.index, "Impl %r does not have the expected index %r (is %r)" % (impl, i, impl.index))
+
+ def test_get_impls_from_file(self):
+ self.assert_read_impls_equal(
+ [],
+ 'layer1/implml/none.implml')
+
+ file = 'layer1/implml/single1.implml'
+ self.assert_read_impls_equal(
+ [MockImpl(['MockReader1', file, {'x': '1'}, {'y': '2'}, {'z': '3'}])],
+ file)
+
+ file = 'layer1/implml/single2.implml'
+ self.assert_read_impls_equal(
+ [MockImpl(['MockReader2', file])],
+ file)
+
+ file = 'layer1/implml/single3.implml'
+ self.assert_read_impls_equal(
+ [MockImpl(['MockReader3', file, {'x': '1'}])],
+ file)
+
+ file = 'layer1/implml/multi1.implml'
+ self.assert_read_impls_equal(
+ [MockImpl(['MockReader1', file, {'x': '1', 'y': '2'}]),
+ MockImpl(['MockReader2', file, {'x': '10', 'y': '20'}]),
+ MockImpl(['MockReader3', file, {'x': '100', 'y': '200'}, {'z': '300'}])],
+ file)
+
+ file = 'layer1/implml/multi2.implml'
+ self.assert_read_impls_equal(
+ [MockImpl(['MockReader1', file, {'x': '1', 'y': '2'}]),
+ MockImpl(['MockReader2', file, {'x': '10', 'y': '20'}]),
+ MockImpl(['MockReader3', file, {'x': '100', 'y': '200'}, {'z': '300'}])],
+ file)
+
+ file = 'layer1/implml/multi3.implml'
+ self.assert_read_impls_equal(
+ [MockImpl(['MockReader1', file, {'x': '1', 'y': '2'}]),
+ MockImpl(['MockReader2', file, {'x': '1', 'y': '2'}]),
+ MockImpl(['MockReader1', file, {'a': '1', 'b': '2'}]),
+ MockImpl(['MockReader2', file, {'a': '1', 'b': '2'}]),],
+ file)
+
+ file = 'layer1/implml/ignored_ns_1.mock3ml'
+ self.assert_read_impls_equal([MockImpl(['MockReader3', file, {'x': '1'}])], file)
+
+ file = 'layer1/implml/ignored_ns_2.mock3ml'
+ self.assert_read_impls_equal([MockImpl(['MockReader3', file, {'x': '1'}])], file)
+
+
+ self.assert_read_impls_equal([], 'layer1/implml/unsupported1.implml')
+ self.assert_read_impls_equal([], 'layer1/implml/unsupported2.implml')
+
+ self.assert_read_impls_equal([], 'layer1/implml/broken.implml')
+
+ def test_is_supported_impl_file(self):
+ def check(filename, expected):
+ self.assertEquals(expected, plugin.ImplFactory.is_supported_impl_file(filename))
+ check('test.implml', True)
+ check('layer/implml/test.implml', True)
+ check('layer/implml/test.mock1ml', True)
+ check('layer/implml/test.mock2ml', True)
+ check('layer/implml/test.mock3ml', True)
+ check('layer/implml/test.test3ml', True)
+ check('layer/implml/test.dummyml', False)
+ check('layer/implml/test.xml', False)
+ check('layer/implml/test', False)
+ check('layer/implml/test.IMPLML', True)
+ check('layer/implml/test.ImplML', True)
+ check('layer/implml/test.Mock1ML', True)
+
+ def test_read_all_impls(self):
+ actual = list(plugin.get_impl_set(mock_config))
+ actual_impls = []
+ for impl in actual:
+ if isinstance(impl, plugin.ImplContainer):
+ actual_impls += impl.get_all_implementations()
+ else:
+ actual_impls.append(impl)
+
+ expected = [
+ MockImpl(['MockReader1', 'layer1/implml/single1.implml', {'x': '1'}, {'y': '2'}, {'z': '3'}]),
+ MockImpl(['MockReader2', 'layer1/implml/single2.implml']),
+ MockImpl(['MockReader3', 'layer1/implml/single3.implml', {'x': '1'}]),
+
+ MockImpl(['MockReader1', 'layer1/implml/single1.mock1ml', {'x': '1'}, {'y': '2'}, {'z': '3'}]),
+ MockImpl(['MockReader2', 'layer1/implml/single2.mock2ml']),
+ MockImpl(['MockReader3', 'layer1/implml/single3.mock3ml', {'x': '1'}]),
+
+ MockImpl(['MockReader3', 'layer1/implml/single3.test3ml', {'x': '1'}]),
+
+ MockImpl(['MockReader3', 'layer1/implml/ignored_ns_1.mock3ml', {'x': '1'}]),
+ MockImpl(['MockReader3', 'layer1/implml/ignored_ns_2.mock3ml', {'x': '1'}]),
+
+ MockImpl(['MockReader1','layer1/implml/multi1.implml', {'y': '2', 'x': '1'}]),
+ MockImpl(['MockReader2', 'layer1/implml/multi1.implml', {'y': '20', 'x': '10'}]),
+ MockImpl(['MockReader3', 'layer1/implml/multi1.implml', {'y': '200', 'x': '100'}, {'z': '300'}]),
+
+ MockImpl(['MockReader1', 'layer1/implml/multi2.implml', {'x': '1', 'y': '2'}]),
+ MockImpl(['MockReader2', 'layer1/implml/multi2.implml', {'x': '10', 'y': '20'}]),
+ MockImpl(['MockReader3', 'layer1/implml/multi2.implml', {'x': '100', 'y': '200'}, {'z': '300'}]),
+
+ MockImpl(['MockReader1', 'layer1/implml/multi3.implml', {'x': '1', 'y': '2'}]),
+ MockImpl(['MockReader2', 'layer1/implml/multi3.implml', {'x': '1', 'y': '2'}]),
+ MockImpl(['MockReader1', 'layer1/implml/multi3.implml', {'a': '1', 'b': '2'}]),
+ MockImpl(['MockReader2', 'layer1/implml/multi3.implml', {'a': '1', 'b': '2'}]),
+ ]
+
+ if sorted(expected) != sorted(actual_impls):
+ print 50 * '-'
+ for impl in sorted(expected): print impl
+ print 50 * '-'
+ for impl in sorted(actual_impls): print impl
+ print 50 * '-'
+
+
+ self.assertEquals(sorted(expected), sorted(actual_impls))
+
+
+class TestTempFeatureDefinition(unittest.TestCase):
+
+ def setUp(self):
+ plugin.ImplFactory.set_reader_classes_override(MOCK_READER_CLASSES)
+
+ def tearDown(self):
+ plugin.ImplFactory.set_reader_classes_override(None)
+
+ def assert_contains_feature(self, config, ref, type, value):
+ dview = config.get_default_view()
+ feature = dview.get_feature(ref)
+ self.assertEquals(type, feature.get_type())
+ self.assertEquals(value, feature.get_value())
+
+ def test_create_feature(self):
+ config = api.Configuration("test.confml")
+ def add_feature(setting_ref, value):
+ config.add_feature(api.Feature(setting_ref), "ExistingFeature")
+ config.add_data(api.Data(fqr="ExistingFeature." + setting_ref, value=value))
+ add_feature('String', 'existing value')
+ add_feature('Boolean', '0')
+ add_feature('Boolean2', 'true')
+
+ Tfd = _plugin_reader.TempVariableDefinition
+ feadefs = [Tfd('TempFeature.String', 'string', 'testing'),
+ Tfd('TempFeature.Int', 'int', '500'),
+ Tfd('TempFeature.Real', 'real', '1.5'),
+ Tfd('TempFeature.Boolean', 'boolean', 'true'),
+ Tfd('TempFeature.String2', 'string', 'xyz ${ExistingFeature.String} zyx'),
+ Tfd('TempFeature.Boolean2', 'boolean', '${ExistingFeature.Boolean}'),
+ Tfd('TempFeature.Boolean3', 'boolean', '${ExistingFeature.Boolean2}')]
+ for feadef in feadefs:
+ feadef.create_feature(config)
+
+ # This needs to be done or the default view won't be up-to-date
+ config.recreate_default_view()
+
+ self.assert_contains_feature(config, 'TempFeature.String', 'string', 'testing')
+ self.assert_contains_feature(config, 'TempFeature.Int', 'int', 500)
+ self.assert_contains_feature(config, 'TempFeature.Real', 'real', 1.5)
+ self.assert_contains_feature(config, 'TempFeature.Boolean', 'boolean', True)
+ self.assert_contains_feature(config, 'TempFeature.String2', 'string', 'xyz existing value zyx')
+ self.assert_contains_feature(config, 'TempFeature.Boolean2', 'boolean', False)
+ self.assert_contains_feature(config, 'TempFeature.Boolean3', 'boolean', True)
+
+ def test_create_seq_feature(self):
+ Tsfd = _plugin_reader.TempVariableSequenceDefinition
+ feadef = Tsfd('TempFeature.Seq', [('String', 'string'),
+ ('Int', 'int'),
+ ('Real', 'real'),
+ ('Boolean', 'boolean'),
+ ('DefaultType', 'string')])
+ config = api.Configuration("test.confml")
+ feadef.create_feature(config)
+ self.assert_contains_feature(config, 'TempFeature.Seq', 'sequence', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.String', 'string', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.Int', 'int', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.Real', 'real', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.Boolean', 'boolean', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.DefaultType', 'string', [])
+
+ fea = config.get_default_view().get_feature('TempFeature.Seq')
+ fea.set_value([['test', '1', '2.0', 'true', 'foo']])
+ self.assertEquals(fea.get_value(), [['test', '1', '2.0', 'true', 'foo']])
+
+ def _create_mock_impl(self, temp_var_defs):
+ impl = Mock()
+ impl.ref = "test.implml"
+ impl.get_temp_variable_definitions = lambda: temp_var_defs
+ return impl
+
+ def test_create_from_impl_container(self):
+ impls = plugin.ImplSet()
+ Tfd = _plugin_reader.TempVariableDefinition
+ Tsfd = _plugin_reader.TempVariableSequenceDefinition
+
+ feadefs = [Tfd('TempFeature.String', 'string', 'testing'),
+ Tfd('TempFeature.Int', 'int', '500')]
+ impls.add_implementation(self._create_mock_impl(feadefs))
+
+ feadefs = [Tfd('TempFeature.Real', 'real', '1.5'),
+ Tfd('TempFeature.Boolean', 'boolean', 'true')]
+ impls.add_implementation(self._create_mock_impl(feadefs))
+
+ feadefs = [Tsfd('TempFeature.Seq', [('String', 'string'),
+ ('Int', 'int'),
+ ('Real', 'real'),
+ ('Boolean', 'boolean')])]
+ impls.add_implementation(self._create_mock_impl(feadefs))
+
+ config = api.Configuration("test.confml")
+ impls.create_temp_features(config)
+
+ self.assert_contains_feature(config, 'TempFeature.String', 'string', 'testing')
+ self.assert_contains_feature(config, 'TempFeature.Int', 'int', 500)
+ self.assert_contains_feature(config, 'TempFeature.Real', 'real', 1.5)
+ self.assert_contains_feature(config, 'TempFeature.Boolean', 'boolean', True)
+ self.assert_contains_feature(config, 'TempFeature.Seq', 'sequence', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.String', 'string', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.Int', 'int', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.Real', 'real', [])
+ self.assert_contains_feature(config, 'TempFeature.Seq.Boolean', 'boolean', [])
+
+
+ def test_create_from_impl_container_with_duplicates(self):
+ impls = plugin.ImplSet()
+
+ Tfd = _plugin_reader.TempVariableDefinition
+ feadefs = [Tfd('TempFeature.String', 'string', 'testing'),
+ Tfd('TempFeature.Int', 'int', '500')]
+ impls.add_implementation(self._create_mock_impl(feadefs))
+
+ feadefs = [Tfd('TempFeature.Real', 'real', '1.5'),
+ Tfd('TempFeature.Boolean', 'boolean', 'true'),
+ Tfd('TempFeature.Int', 'int', '500')]
+ impls.add_implementation(self._create_mock_impl(feadefs))
+
+ config = api.Configuration("test.confml")
+ self.assertRaises(exceptions.AlreadyExists, impls.create_temp_features, config)
+
+ def test_create_from_impl_container_with_existing(self):
+ impls = plugin.ImplSet()
+
+ Tfd = _plugin_reader.TempVariableDefinition
+ feadefs = [Tfd('TempFeature.String', 'string', 'testing'),
+ Tfd('TempFeature.Int', 'int', '500')]
+ impls.add_implementation(self._create_mock_impl(feadefs))
+
+ feadefs = [Tfd('TempFeature.Real', 'real', '1.5'),
+ Tfd('TempFeature.Boolean', 'boolean', 'true')]
+ impls.add_implementation(self._create_mock_impl(feadefs))
+
+ config = api.Configuration("test.confml")
+ config.add_feature(api.Feature("Int"), "TempFeature")
+ self.assertRaises(exceptions.AlreadyExists, impls.create_temp_features, config)
+
+class TestCommonImplmlDataReader(unittest.TestCase):
+
+ def _read_data(self, xml_data):
+ etree = utils.etree.fromstring(xml_data)
+ return _plugin_reader.CommonImplmlDataReader.read_data(etree)
+
+ def test_simple_all_tags(self):
+ XML = """
+
+
+
+
+
+
+
+
+
+
+
+ """
+ actual = self._read_data(XML)
+
+ expected = _plugin_reader.CommonImplmlData()
+ expected.phase = 'pre'
+ expected.tags = {'target': ['rofs3']}
+ expected.tempvar_defs = [Tfd('Temp.Feature', 'string', 'test'),
+ Tsfd('Temp.SeqFeature', [('Sub', 'int')])]
+ expected.setting_refs_override = Sro(['Foo.Bar'])
+ expected.output_root_dir = 'output_root'
+ expected.output_sub_dir = 'output_sub'
+
+ self.assertEquals(actual, expected)
+
+ def test_invalid_phases(self):
+ XML = """
+
+ """
+ self.assertRaises(exceptions.ParseError, self._read_data, XML)
+
+ XML = """
+
+ """
+ self.assertRaises(exceptions.ParseError, self._read_data, XML)
+
+ def test_valid_phases(self):
+ def run_test(phase ):
+ xml_data = """
+
+ """ % phase
+ actual = self._read_data(xml_data)
+ expected = _plugin_reader.CommonImplmlData()
+ expected.phase = phase
+ self.assertEquals(actual, expected)
+
+ run_test('pre')
+ run_test('normal')
+ run_test('post')
+
+ def test_invalid_temp_features(self):
+ def run_test(element_xml_data):
+ xml_data = """
+ %s
+ """ % element_xml_data
+ self.assertRaises(exceptions.ParseError, self._read_data, xml_data)
+
+ run_test(' ')
+ run_test(' ')
+ run_test(' ')
+
+ run_test(' ')
+ run_test(' ')
+ run_test(' ')
+ run_test(' ')
+
+ def test_valid_temp_feature_types(self):
+ def run_test(type):
+ # Test for simple features
+ xml_data = """
+
+ """ % type
+ actual = self._read_data(xml_data)
+ expected = _plugin_reader.CommonImplmlData()
+ expected.tempvar_defs = [Tfd('Foo.Bar', type, '')]
+ self.assertEquals(actual, expected)
+
+ # Test for sequence features
+ xml_data = """
+
+
+
+ """ % type
+ actual = self._read_data(xml_data)
+ expected = _plugin_reader.CommonImplmlData()
+ expected.tempvar_defs = [Tsfd('Foo.Bar', [('Sub', type)])]
+ self.assertEquals(actual, expected)
+
+ run_test('string')
+ run_test('int')
+ run_test('real')
+ run_test('boolean')
+
+ def test_setting_refs_override(self):
+ def check(xml, expected_refs):
+ xml = '%s ' % xml
+ actual = self._read_data(xml)
+ expected = _plugin_reader.CommonImplmlData()
+ expected.setting_refs_override = Sro(expected_refs)
+ self.assertEquals(actual, expected)
+
+ check(' ', [])
+ check(' ', [])
+ check(' ', None)
+ check("""
+
+
+
+ """,
+ ['Foo.Bar'])
+ check("""
+
+
+
+
+
+ """,
+ ['Foo.Bar', 'Foo.Baz', 'Test.Setting'])
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_plugin_implcontainer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_plugin_implcontainer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,298 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os
+import logging
+import __init__
+from cone.public import *
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+
+
+class TestPluginImplContainer(unittest.TestCase):
+ class ImplTest(plugin.ImplBase):
+ def __init__(self,ref,configuration):
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.generate_invoked = False
+ self.refs = ["dummy1.too"]
+ self.output_files = []
+ def generate(self, context=None):
+ self.generate_invoked = True
+ if context and hasattr(context, 'objects'):
+ context.objects.append(self)
+
+ def get_refs(self):
+ return self.refs
+
+ def list_output_files(self):
+ return self.output_files
+
+ def test_impl_container_add(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = plugin.ImplBase("implml/test.content",None)
+ imp2a = plugin.ImplBase("implml/copy:21.content",None)
+ imp2b = plugin.ImplBase("implml/copy:24.content",None)
+ container.append(imp1)
+ container.append(imp2a)
+ container.append(imp2b)
+ self.assertEquals(container.impls, [imp1,imp2a, imp2b])
+
+ def test_impl_container_sub_container(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = plugin.ImplBase("implml/test.content",None)
+ container.append(imp1)
+ subcontainer = plugin.ImplContainer("implml/sub.implml", None)
+ imp2a = plugin.ImplBase("implml/sub.implml:21.content",None)
+ imp2b = plugin.ImplBase("implml/sub.implml:24.content",None)
+ subcontainer.append(imp2a)
+ subcontainer.append(imp2b)
+ container.append(subcontainer)
+ self.assertEquals(container.get_all_implementations(),[imp1,imp2a,imp2b])
+ for sub in container:
+ print sub
+ self.assertEquals(container.impls, [imp1,subcontainer])
+ container[0] = subcontainer
+ self.assertEquals(container.impls, [subcontainer,subcontainer])
+ del container[0]
+ self.assertEquals(container.impls, [subcontainer])
+
+ def test_impl_container_with_condition(self):
+ context = plugin.GenerationContext()
+ context.configuration = api.Configuration()
+ context.configuration.add_feature(api.Feature("test"))
+ context.configuration.add_feature(api.Feature("stringsub"),"test")
+ context.configuration.add_feature(api.Feature("intsub"),"test")
+ context.configuration.get_default_view().test.value = True
+ context.configuration.get_default_view().test.stringsub.value = "stringval"
+ context.configuration.get_default_view().test.intsub.value = 2
+
+ condition = rules.SimpleCondition("${test}", "true")
+ container = plugin.ImplContainer("norm", None)
+ container.condition = condition
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ container.append(imp1)
+ container.generate(context)
+ self.assertTrue(imp1.generate_invoked)
+ imp1.generate_invoked = False
+ context.configuration.get_default_view().test.value = False
+ container.generate(context)
+ self.assertFalse(imp1.generate_invoked)
+
+ imp1.generate_invoked = False
+ condition = rules.SimpleCondition("${test}", "false")
+ container.condition = condition
+ container.append(imp1)
+ container.generate(context)
+ self.assertTrue(imp1.generate_invoked)
+ imp1.generate_invoked = False
+ context.configuration.get_default_view().test.value = True
+ container.generate(context)
+ self.assertFalse(imp1.generate_invoked)
+
+
+ def test_impl_container_generate(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ container.append(imp1)
+ container.append(imp2a)
+ container.append(imp2b)
+ container.generate()
+ self.assertTrue(imp1.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+
+ def test_impl_container_get_tags(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ subcontainer = plugin.ImplContainer("sub", None)
+ container.append(imp1)
+ container.append(imp2a)
+ container.append(imp2b)
+ container.append(subcontainer)
+ self.assertEquals(container.get_tags(), {})
+ container.set_tags({'test':['foobar']})
+ self.assertEquals(container.get_tags(), {'test':['foobar']})
+ imp1.set_tags({'foo':['bar']})
+ self.assertEquals(container.get_tags(), {'test':['foobar'],
+ 'foo':['bar']})
+ imp2a.set_tags({'test':['bar'], 'one' :['more']})
+
+ self.assertEquals(container.get_tags(), {'test':['foobar', 'bar'],
+ 'foo':['bar'],
+ 'one' :['more']})
+ subcontainer.set_tags({'test':['bar1']})
+ self.assertEquals(container.get_tags(), {'test':['foobar', 'bar', 'bar1'],
+ 'foo':['bar'],
+ 'one' :['more']})
+
+ def test_impl_container_get_phase(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ subcontainer1 = plugin.ImplContainer("norm", None)
+ container.append(subcontainer1)
+ subcontainer1.append(imp1)
+ subcontainer1.append(imp2a)
+ subcontainer1.append(imp2b)
+ subcontainer1.set_invocation_phase("normal")
+ self.assertEquals(container.invocation_phase(), ["normal"])
+ imp1.set_invocation_phase('pre')
+ self.assertEquals(container.invocation_phase(), ["normal"])
+ subcontainer2 = plugin.ImplContainer("norm", None)
+ subimp = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ subimp.set_invocation_phase('post')
+ subcontainer2.append(subimp)
+ subcontainer2.set_invocation_phase('post')
+ container.append(subcontainer2)
+ self.assertEquals(container.invocation_phase(), ['post','normal'])
+
+ def test_impl_container_get_refs(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ container.append(imp1)
+ container.append(imp2a)
+ container.append(imp2b)
+ self.assertEquals(container.get_refs(), ["dummy1.too"])
+ imp2b.refs = ['dummy2.foo']
+ self.assertEquals(container.get_refs(), ["dummy1.too",
+ "dummy2.foo",])
+
+ def test_impl_container_list_output_files(self):
+ container = plugin.ImplContainer("norm", None)
+ subcontainer = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ container.append(subcontainer)
+ subcontainer.append(imp1)
+ subcontainer.append(imp2a)
+ subcontainer.append(imp2b)
+ self.assertEquals(container.list_output_files(), [])
+ imp2b.output_files= ['output/dummy2.txt']
+ self.assertEquals(container.list_output_files(), ['output/dummy2.txt'])
+ imp1.output_files= ['output/foobar/hee.txt']
+ self.assertEquals(container.list_output_files(), ['output/foobar/hee.txt',
+ 'output/dummy2.txt'])
+
+ def test_impl_container_set_output_root(self):
+ container = plugin.ImplContainer("norm", None)
+ subcontainer = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ container.append(subcontainer)
+ subcontainer.append(imp1)
+ subcontainer.append(imp2a)
+ subcontainer.append(imp2b)
+ self.assertEquals(imp1.get_output_root(), 'output')
+ container.set_output_root('foobar/test')
+ self.assertEquals(imp1.get_output_root(), 'foobar/test')
+
+ def test_impl_container_sub_container_generate(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ container.append(imp1)
+ subcontainer = plugin.ImplContainer("implml/sub.implml", None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ subcontainer.append(imp2a)
+ subcontainer.append(imp2b)
+ container.append(subcontainer)
+ self.assertEquals(container.impls, [imp1,subcontainer])
+ container.append(subcontainer)
+ container.generate()
+ self.assertTrue(imp1.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+
+ def test_impl_container_sub_container_generate_with_generation_contexts(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ container.append(imp1)
+ subcontainer = plugin.ImplContainer("implml/sub.implml", None)
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ subcontainer.append(imp2a)
+ subcontainer.append(imp2b)
+ container.append(subcontainer)
+ self.assertEquals(container.impls, [imp1,subcontainer])
+ context = plugin.GenerationContext()
+ context.objects = []
+ container.generate(context)
+ self.assertTrue(imp1.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertEquals(len(context.objects), 3)
+ self.assertEquals(context.objects, [imp1,imp2a,imp2b])
+
+ def test_impl_container_generate_with_generation_contexts_tags(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ subcontainer1 = plugin.ImplContainer("implml/sub1.implml", None)
+ subcontainer1.append(imp1)
+
+ subcontainer2 = plugin.ImplContainer("implml/sub2.implml", None)
+ subcontainer2.set_tags({'target': ['rofs3','uda']})
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ subcontainer2.append(imp2a)
+ subcontainer2.append(imp2b)
+ container.append(subcontainer1)
+ container.append(subcontainer2)
+
+ context = plugin.GenerationContext()
+ context.tags = {'target': ['rofs3'], 'foobar' :['test']}
+ context.objects = []
+ container.generate(context)
+ self.assertFalse(imp1.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertEquals(len(context.objects), 2)
+ self.assertEquals(context.objects, [imp2a,imp2b])
+
+ def test_impl_container_generate_with_generation_phase(self):
+ container = plugin.ImplContainer("norm", None)
+ imp1 = TestPluginImplContainer.ImplTest("implml/test.content",None)
+ subcontainer1 = plugin.ImplContainer("implml/sub1.implml", None)
+ subcontainer1.append(imp1)
+
+ subcontainer2 = plugin.ImplContainer("implml/sub2.implml", None)
+ subcontainer2.set_invocation_phase("post")
+ imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+ imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+ subcontainer2.append(imp2a)
+ subcontainer2.append(imp2b)
+ container.append(subcontainer1)
+ container.append(subcontainer2)
+
+ context = plugin.GenerationContext()
+ context.phase = "post"
+ context.objects = []
+ container.generate(context)
+ self.assertFalse(imp1.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertTrue(imp2a.generate_invoked)
+ self.assertEquals(len(context.objects), 2)
+ self.assertEquals(context.objects, [imp2a,imp2b])
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_plugin_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_plugin_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,214 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os
+import logging
+import __init__
+from cone.public import *
+from cone.public import _plugin_reader
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class ImplTest(plugin.ImplBase):
+ def __init__(self,ref,configuration):
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.generate_invoked = False
+ self.refs = ["dummy1.too"]
+ self.output_files = []
+ def generate(self, context=None):
+ self.generate_invoked = True
+ if context and hasattr(context, 'objects'):
+ context.objects.append(self)
+
+ def get_refs(self):
+ return self.refs
+
+ def list_output_files(self):
+ return self.output_files
+
+
+class TestPluginReader(unittest.TestCase):
+ def setUp(self):
+ pass
+
+class TestCommonNamespaceHandling(unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+
+ def tearDown(self):
+ pass
+
+ def test_implcontainer_reader_get_condition(self):
+ root = utils.etree.fromstring(" ")
+ self.assertEquals(plugin.ImplContainerReader.get_condition(root), None)
+
+ root = utils.etree.fromstring(" ")
+ condition = plugin.ImplContainerReader.get_condition(root)
+ self.assertTrue(isinstance(condition, rules.SimpleCondition))
+ self.assertEquals(condition.left.expression, "test")
+ self.assertEquals(condition.right.expression, "true")
+
+ root = utils.etree.fromstring(" ")
+ condition = plugin.ImplContainerReader.get_condition(root)
+ self.assertTrue(isinstance(condition, rules.SimpleCondition))
+ self.assertEquals(condition.left.expression, "${feature.one}")
+ self.assertEquals(condition.right.expression, "2")
+
+
+ def test_implcontainer_reader_get_reader_classes(self):
+ classes = plugin.ImplContainerReader.get_reader_classes()
+ self.assertTrue(classes.has_key('http://www.symbianfoundation.org/xml/implml/1'))
+
+ def test_get_test_container(self):
+ xml_data = """
+
+
+ """
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ self.assertTrue(isinstance(container, plugin.ImplContainer))
+
+ def test_get_test_container_with_sub_containers(self):
+ xml_data = """
+
+
+
+
+
+
+
+ """
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ self.assertTrue(isinstance(container, plugin.ImplContainer))
+ self.assertEquals(len(container), 3)
+
+ def test_containers_with_phases(self):
+ xml_data = """
+
+
+
+
+
+
+
+ """
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ self.assertEquals(container.invocation_phase(), ['post','normal'])
+ self.assertEquals(container[2].invocation_phase(), ['post'])
+
+ def test_containers_with_tags(self):
+ xml_data = """
+
+
+
+
+
+
+
+
+
+
+ """
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ self.assertEquals(container[2].get_tags(), {'target': ['rofs3']})
+ self.assertEquals(container.get_tags(), {'target': ['rofs2','rofs3'],
+ 'foobar': ['test']})
+
+ def test_tempfeature_definitions(self):
+ xml_data = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ """
+
+ Tfd = _plugin_reader.TempVariableDefinition
+ Tsfd = _plugin_reader.TempVariableSequenceDefinition
+ expected_1 = [
+ Tfd('TempFeature.String', 'string', 'testing'),
+ Tfd('TempFeature.Int', 'int', '500'),
+ Tfd('TempFeature.Real', 'real', '1.5'),
+ Tfd('TempFeature.Boolean', 'boolean', 'true'),
+ Tfd('TempFeature.Defaults', 'string', ''),
+ Tsfd('TempFeature.Seq', [('String', 'string'),
+ ('Int', 'int',),
+ ('Real', 'real'),
+ ('Boolean', 'boolean'),
+ ('DefaultType', 'string')]),
+ ]
+ expected_2 = [Tfd('TempFeature.root', 'string', value='true')] + expected_1
+
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ self.assertEquals(container[0].get_temp_variable_definitions(), expected_1)
+ self.assertEquals(container.get_temp_variable_definitions(), expected_2)
+
+ def test_get_test_container_with_condition(self):
+ xml_data = """
+
+
+ """
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ self.assertTrue(isinstance(container.condition, rules.SimpleCondition))
+ self.assertEquals(container.condition.left.expression, "${feature.test}")
+ self.assertEquals(container.condition.right.expression, "true")
+
+ xml_data = """
+
+
+ """
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ self.assertTrue(isinstance(container.condition, rules.SimpleCondition))
+ self.assertEquals(container.condition.left.expression, "${feature.test}")
+ self.assertEquals(container.condition.right.expression, "false")
+
+ def test_impl_container_with_condition(self):
+ context = plugin.GenerationContext()
+ context.configuration = api.Configuration()
+ context.configuration.add_feature(api.Feature("test"))
+ context.configuration.get_default_view().test.value = True
+
+ xml_data = """
+
+
+ """
+ container = plugin.ImplContainerReader.read_implementation(xml_data)
+ imp1 = ImplTest("implml/test.content",None)
+ container.append(imp1)
+ container.generate(context)
+ self.assertFalse(imp1.generate_invoked)
+ context.configuration.get_default_view().test.value = False
+ container.generate(context)
+ self.assertTrue(imp1.generate_invoked)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_project.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_project.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,293 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the CPF configuration
+"""
+import unittest
+import string
+import sys,os,shutil
+
+import __init__
+
+from cone.public import *
+#from cone.public import stringstorage
+from cone.storage import persistentdictionary
+
+class TestProjectOpen(unittest.TestCase):
+
+ def test_open_project(self):
+
+ p = api.Project(api.Storage(""))
+ self.assertTrue(p)
+
+ def test_open_project_of_non_storage(self):
+ fs = ""
+ try:
+ p = api.Project(fs)
+ self.fail("Opening on top of non storage succeeds!!")
+ except exceptions.StorageException:
+ self.assertTrue(True)
+
+class TestProjectConfigurations(unittest.TestCase):
+ def setUp(self):
+ self.prj = api.Project(api.Storage(""))
+
+ def test_create_configuration(self):
+ self.prj.create_configuration("test.confml")
+ self.assertTrue(self.prj.test_confml)
+ self.assertEquals(self.prj.test_confml.get_path(),"test.confml")
+
+ def test_create_and_getconfiguration(self):
+ self.prj.create_configuration("test.confml")
+ self.assertEquals(self.prj.get_configuration("test.confml").get_path(), "test.confml")
+
+ def test_create_multi_and_list(self):
+ self.prj.create_configuration("test1.confml")
+ self.prj.create_configuration("test2.confml")
+ self.prj.create_configuration("test3.confml")
+ self.assertEquals(self.prj.list_configurations(), ["test1.confml",
+ "test2.confml",
+ "test3.confml"])
+
+ def test_create_multi_and_list_with_filters(self):
+ self.prj.create_configuration("test1.confml")
+ self.prj.create_configuration("test2.confml")
+ self.prj.create_configuration("test3.confml")
+ self.prj.create_configuration("test4.confml")
+ self.prj.create_configuration("foo1.confml")
+ self.prj.create_configuration("foo2.confml")
+ self.assertEquals(self.prj.list_configurations(r'test[24]\.confml'),
+ ["test2.confml",
+ "test4.confml"])
+ self.assertEquals(self.prj.list_configurations([r'test[24]\.confml', r'foo\d\.confml']),
+ ["test2.confml",
+ "test4.confml",
+ "foo1.confml",
+ "foo2.confml"])
+
+ def test_create_multi_and_remove_one(self):
+ self.prj.create_configuration("test1.confml")
+ self.prj.create_configuration("test2.confml")
+ self.prj.create_configuration("test3.confml")
+ self.prj.remove_configuration("test2.confml")
+ self.assertEquals(self.prj.list_configurations(), ["test1.confml",
+ "test3.confml"])
+
+ def test_create_multi_and_remove_all(self):
+ self.prj.create_configuration("test1.confml")
+ self.prj.create_configuration("test2.confml")
+ self.prj.create_configuration("test3.confml")
+ for c in self.prj.list_configurations():
+ self.prj.remove_configuration(c)
+ self.assertEquals(self.prj.list_configurations(), [])
+
+ def test_create_multi_and_add_subconfigurations(self):
+ self.prj.create_configuration("test1.confml")
+ self.prj.create_configuration("test2.confml")
+ self.prj.create_configuration("test3.confml")
+ self.prj.test2_confml.create_configuration("foo/root.confml")
+ conf = self.prj.test2_confml.create_configuration("fii/root.confml")
+ #self.assertEquals(conf.get_full_path(),'')
+ self.assertTrue(self.prj.is_configuration("test3.confml"))
+ # TODO: this is not working at the moment due to performance problem in
+ # Project.list_all_configurations()
+ # self.assertTrue(self.prj.is_configuration("fii/root.confml"))
+
+ self.assertEquals(self.prj.list_configurations(), ["test1.confml",
+ "test2.confml",
+ "test3.confml"])
+
+ self.assertEquals(self.prj.test2_confml.list_configurations(), ["foo/root.confml",
+ "fii/root.confml",])
+
+ def test_create_multi_and_add_subconfigurations_and_features(self):
+ self.prj.create_configuration("test1.confml")
+ self.prj.create_configuration("test2.confml")
+ self.prj.create_configuration("test3.confml")
+ self.prj.test2_confml.create_configuration("foo/root.confml")
+ self.prj.test2_confml.create_configuration("fii/root.confml")
+ self.prj.test2_confml.foo__root_confml.add_feature(api.Feature("testfea1"))
+ self.prj.test2_confml.foo__root_confml.add_feature(api.Feature("testfea2"))
+ self.prj.test2_confml.foo__root_confml.add_feature(api.Feature("testfea11"),"testfea1")
+ self.prj.test2_confml.fii__root_confml.add_feature(api.Feature("testfea3"))
+ self.prj.test2_confml.fii__root_confml.add_feature(api.Feature("testfea4"))
+ self.prj.test2_confml.fii__root_confml.add_feature(api.Feature("testfea31"),"testfea3")
+ self.assertEquals(self.prj.test2_confml.list_all_features(), ['testfea1',
+ 'testfea1.testfea11',
+ 'testfea2',
+ 'testfea3',
+ 'testfea3.testfea31',
+ 'testfea4'])
+
+
+class TestProjectConfigurationsStorage(unittest.TestCase):
+ def test_create_configuration_and_store_storage(self):
+ prj = api.Project(api.Storage.open("temp/testproject.pk", "w"))
+ prj.create_configuration("test.confml")
+ prj.close()
+ self.assertTrue(os.path.exists("temp/testproject.pk"))
+ shutil.rmtree("temp")
+
+ def test_create_configuration_and_store_storage_and_open(self):
+ prj = api.Project(api.Storage.open("temp/testproject1.pk","w"))
+ config = prj.create_configuration("test.confml")
+ config.desc = "Descriptions"
+ prj.save()
+ prj.close()
+
+ prj2 = api.Project(api.Storage.open("temp/testproject1.pk"))
+ self.assertEquals(prj2.list_configurations(), ['test.confml'])
+ self.assertEquals(prj2.test_confml.desc, "Descriptions")
+ shutil.rmtree("temp")
+
+ def test_create_configuration_hierarchy_and_store_storage_and_open(self):
+ prj = api.Project(api.Storage.open("temp/testproject2.pk","w"))
+ config = prj.create_configuration("test.confml")
+ config.desc = "Descriptions"
+ prj.test_confml.create_configuration("s60/root.confml")
+ prj.test_confml.s60__root_confml.add_feature(api.Feature("feature1"))
+ prj.test_confml.create_configuration("ncp/root.confml")
+ prj.save()
+ prj.close()
+
+ prj2 = api.Project(api.Storage.open("temp/testproject2.pk"))
+ self.assertEquals(prj2.list_configurations(), ['test.confml'])
+ self.assertEquals(prj2.test_confml.desc, "Descriptions")
+ self.assertEquals(prj2.test_confml.list_all_features(),['feature1'])
+ prj2.close()
+ shutil.rmtree("temp")
+
+ def test_dump_configuration_with_include(self):
+ prj = api.Project(api.Storage.open("temp/testprojectinc.pk","w"))
+ config = prj.create_configuration("test.confml")
+ config.include_configuration("foo/foo.confml")
+ dumped = persistentdictionary.DictWriter().dumps(config)
+ children = dumped['Configuration']['children']
+ self.assertEquals(children,[{'ConfigurationProxy': {'dict': {'path': 'foo/foo.confml'}}}])
+ prj.close()
+ shutil.rmtree("temp")
+
+ def test_create_configuration_project_with_includes_and_reopen_storage(self):
+ prj = api.Project(api.Storage.open("temp/testprojectinc2.pk","w"))
+ config = prj.create_configuration("test.confml")
+ config.desc = "Descriptions"
+ config2 = config.create_configuration("foo/foo.confml")
+ config2.add_feature(api.Feature("feature1"))
+ config2.save()
+ config2.close()
+ prj.test_confml.include_configuration("foo/foo.confml")
+ prj.save()
+ prj.close()
+
+ prj2 = api.Project(api.Storage.open("temp/testprojectinc2.pk"))
+ self.assertEquals(prj2.list_configurations(), ['test.confml'])
+ self.assertEquals(prj2.test_confml.list_configurations(), ['foo/foo.confml'])
+ foo = prj2.test_confml.get_configuration('foo/foo.confml')
+ self.assertEquals(prj2.get_configuration('test.confml').list_all_features(), ['feature1'])
+ self.assertEquals(prj2.test_confml.get_default_view().list_features(), ['feature1'])
+ prj2.close()
+ shutil.rmtree("temp")
+
+ def test_create_configuration_project_with_multiincludes_and_reopen_storage(self):
+ prj = api.Project(api.Storage.open("temp/testprojectinc3.pk","w"))
+ config = prj.create_configuration("test.confml")
+ prj.add_configuration(api.Configuration("s60/root.confml", namespace="com.nokia.s60"))
+ prj.create_configuration("foo/foo.confml")
+ prj.test_confml.include_configuration("foo/foo.confml")
+ prj.test_confml.include_configuration("s60/root.confml")
+ foofea = api.Feature("foofea")
+ foofea.add_feature(api.Feature("foofea_setting1"))
+ foofea.add_feature(api.Feature("foofea_setting2"))
+ prj.test_confml.foo__foo_confml.add_feature(foofea)
+
+ s60fea = api.Feature("s60fea")
+ s60fea.add_feature(api.Feature("wlanset1"))
+ s60fea.add_feature(api.Feature("wlan_set2"))
+ prj.test_confml.s60__root_confml.add_feature(s60fea)
+ dview = prj.test_confml.get_default_view()
+ prj.save()
+
+ prj2 = api.Project(api.Storage.open("temp/testprojectinc3.pk"))
+ self.assertEquals(prj2.list_configurations(), ['test.confml'])
+
+ dview2 = prj2.test_confml.get_default_view()
+ self.assertEquals(dview.list_all_features(),
+ dview2.list_all_features())
+ testconf = prj2.get_configuration('test.confml')
+ my_view = testconf.get_default_view()
+ my_view.com.nokia.s60.s60fea.wlanset1.data = 1
+ prj2.close()
+ shutil.rmtree("temp")
+
+ def test_create_configuration_project_with_multiincludes_and_test_layer_actions(self):
+ prj = api.Project(api.Storage.open("temp/testprojectlayers.pk","w"))
+ config = prj.create_configuration("test.confml")
+ prj.add_configuration(api.Configuration("s60/root.confml", namespace="com.nokia.s60"))
+ prj.create_configuration("foo/foo.confml")
+ prj.create_configuration("foo/confml/component.confml").close()
+ prj.test_confml.include_configuration("foo/foo.confml")
+ prj.test_confml.include_configuration("s60/root.confml")
+ prj.test_confml.foo__foo_confml.create_configuration("data.confml")
+ foofea = api.Feature("foofea")
+ foofea.add_feature(api.Feature("foofea_setting1"))
+ foofea.add_feature(api.Feature("foofea_setting2"))
+ prj.test_confml.foo__foo_confml.add_feature(foofea)
+ prj.save()
+ foo_config = prj.test_confml.get_configuration("foo/foo.confml")
+ layer = foo_config.get_layer()
+ res = layer.open_resource("confml/component1.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.content_folder().open_resource("foobar.txt","w")
+ res.write("foo bar")
+ res.close()
+ self.assertEquals(layer.list_confml(), ['confml/component.confml', 'confml/component1.confml'])
+ self.assertEquals(layer.list_content(), ['content/foobar.txt'])
+ self.assertEquals(layer.list_all_resources(), ['confml/component.confml', 'confml/component1.confml', 'content/foobar.txt'])
+ self.assertEquals(foo_config.list_resources(), ['foo/foo.confml','foo/data.confml', 'foo/confml/component.confml', 'foo/confml/component1.confml', 'foo/content/foobar.txt'])
+ self.assertEquals(prj.test_confml.list_resources(), ['test.confml',
+ 'foo/foo.confml',
+ 'foo/data.confml',
+ 's60/root.confml',
+ 'foo/confml/component.confml',
+ 'foo/confml/component1.confml',
+ 'foo/content/foobar.txt'])
+
+
+ s60_config = prj.test_confml.get_configuration("s60/root.confml")
+ layer = s60_config.get_layer()
+ res = layer.open_resource("confml/component1.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.content_folder().open_resource("s60.txt","w")
+ res.write("foo bar")
+ res.close()
+ res = layer.content_folder().open_resource("foobar.txt","w")
+ res.write("foo bar")
+ res.close()
+ self.assertEquals(layer.list_confml(), ['confml/component1.confml'])
+ self.assertEquals(layer.list_content(), ['content/foobar.txt', 'content/s60.txt'])
+ self.assertEquals(prj.test_confml.layered_content().list_keys(), ['foobar.txt', 's60.txt'])
+ self.assertEquals(prj.test_confml.layered_content().get_values('foobar.txt'), ['foo/content/foobar.txt', 's60/content/foobar.txt'])
+ prj.close()
+ shutil.rmtree("temp")
+
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_public_api.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_public_api.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os
+import __init__
+from cone.public import *
+
+class TestPublicApiConfiguration(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_api_configuration_creation(self):
+ config = api.Configuration("test")
+ self.assertTrue(config!=None)
+
+
+class TestPluginFactory(unittest.TestCase):
+ class FactoryTestImplReader(plugin.ReaderBase):
+ FILE_EXTENSIONS = ['factorytest']
+
+ class ConeDummyReader(persistence.ConeReader):
+ @classmethod
+ def supported_elem(cls, elemname):
+ if elemname.lower() == "dummy":
+ return True
+ else:
+ return False
+ def __init__(self):
+ super(persistence.ConeReader,self).__init__()
+
+ class ConeDummyWriter(persistence.ConeWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ if classname.lower() == "dummy":
+ return True
+ else:
+ return False
+
+ def __init__(self):
+ super(persistence.ConeWriter,self).__init__()
+
+
+
+ def test_factory_is_supported_impl_file(self):
+ plugin.ImplFactory.set_reader_classes_override([self.FactoryTestImplReader])
+ try:
+ self.assertTrue(api.Factory().is_supported_impl_file("some_file.factorytest"))
+ self.assertTrue(api.Factory().is_supported_impl_file("SOME_FILE.FACTORYTEST"))
+ self.assertFalse(api.Factory().is_supported_impl_file("some_file.foo"))
+ finally:
+ plugin.ImplFactory.set_reader_classes_override(None)
+
+ def test_get_reader_fails(self):
+ try:
+ api.Factory().get_reader_for_elem("")
+ self.fail("Not existing reader creation succeeds?")
+ except exceptions.ConePersistenceError,e:
+ self.assertTrue(True)
+
+ def test_get_writer_fails(self):
+ try:
+ api.Factory().get_writer_for_class("")
+ self.fail("Not existing writer creation succeeds?")
+ except exceptions.ConePersistenceError,e:
+ self.assertTrue(True)
+
+ def test_get_reader_ok(self):
+ r = api.Factory().get_reader_for_elem("Dummy")
+ self.assertTrue(isinstance(r,TestPluginFactory.ConeDummyReader))
+
+ def test_get_reader_low(self):
+ r = api.Factory().get_reader_for_elem("dummy")
+ self.assertTrue(isinstance(r,TestPluginFactory.ConeDummyReader))
+
+ def test_get_reader_upper(self):
+ r = api.Factory().get_reader_for_elem("DUMMY")
+ self.assertTrue(isinstance(r,TestPluginFactory.ConeDummyReader))
+
+ def test_get_writer_ok(self):
+ r = api.Factory().get_writer_for_class("Dummy")
+ self.assertTrue(isinstance(r,TestPluginFactory.ConeDummyWriter))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_rules.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_rules.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,484 @@
+# *-* coding: utf8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import sys, os
+import __init__
+
+from cone.public.api import CompositeConfiguration, Feature
+from cone.public.rules import ASTInterpreter, RelationContainerImpl, RELATIONS, get_tokens
+from cone.public.rules import ParseException, DefaultContext, BaseRelation, RequireExpression, OPERATORS
+
+#### TEST RELATIONS ####
+
+AA_BA = 'a.a require b.b'
+AB_BB = 'a.b require b.b'
+BA_CA = 'b.a require c.a and c.b and a.b'
+
+CB_DA = 'c.b require d.a'
+DA_DB = 'd.a require d.b'
+
+AC_AB_BA = 'a.c and a.a require b.a'
+
+EA_FSTAR = 'e.a require f.*'
+
+TEST_RELATIONS = {
+ 'a.a' : [AA_BA],
+ 'a.b' : [AB_BB],
+ 'a.c' : [AC_AB_BA],
+ 'b.a' : [BA_CA],
+ 'c.b' : [CB_DA],
+ 'd.a' : [DA_DB],
+ 'e.a' : [EA_FSTAR]
+}
+
+class DummyRelationFactory():
+ def get_relations_for(self, configuration, ref):
+ rels = TEST_RELATIONS.get(ref)
+
+ if rels:
+ relation_container = RelationContainerImpl()
+ for rel in rels:
+ rel_s = rel.split(' ')
+ from_ref = rel_s[0]
+ relation_name = 'require'
+ to_ref = ' '.join(rel_s[2:])
+ relation = RELATIONS.get(relation_name)(configuration, from_ref, to_ref)
+ relation_container.add_relation(relation)
+ propagated_relations = self.get_relations_for(configuration, to_ref)
+ if propagated_relations:
+ for relation in propagated_relations:
+ relation_container.add_relation(relation)
+
+ return relation_container
+ return None
+
+class DummyConfiguration(object):
+ VALUES = {
+ 'a.a' : True,
+ 'a.b' : False,
+ 'a.c' : False,
+ 'b.a' : True,
+ 'b.b' : True,
+ 'c.b' : False,
+ 'd.a' : True,
+ 'e.a' : True,
+ }
+
+ def get_feature(self, ref):
+ return DummyConfiguration.VALUES.get(ref, False)
+
+class DummyContext(DefaultContext):
+ def handle_terminal(self, expression):
+ return DummyConfiguration.VALUES.get(expression, False)
+
+class DummyBaseRelation(BaseRelation):
+ def __init__(self, data, left, right):
+ self.context = DummyContext(data)
+ super(DummyBaseRelation, self).__init__(data, left, right)
+
+class DummyRequireRelation(DummyBaseRelation):
+ KEY = 'require'
+
+ def __init__(self, data, left, right):
+ self.context = DummyContext(data)
+ super(DummyRequireRelation, self).__init__(data, left, right)
+
+RELATIONS[DummyRequireRelation.KEY] = DummyRequireRelation
+OPERATORS['require'] = RequireExpression
+multilines = \
+"""
+APs.AP configures KCRUidCommsDatCreator.KCommsDatCreatorInputFileName = 'VariantData_commsdat.xml' and
+ KCRUidStartupSettings.KCRKeyAccessPointPlugin = '0' and
+ KCRUidStartupSettings.KCRKeyStreamingPlugin = '0' and
+ KCRUidStartupSettings.KCRKeyMusicShopPlugin = '0' and
+ KCRUidStartupSettings.KCRKeyDeviceManagementPlugin = '0' and
+ KCRUidStartupSettings.KCRKeyAGPSPlugin = '0'
+"""
+
+class TestRelations(unittest.TestCase):
+
+ def setUp(self):
+ self.configuration = DummyConfiguration()
+
+ def test_has_ref(self):
+ """
+ Tests the relation and relation container
+ """
+ factory = DummyRelationFactory()
+ rels = factory.get_relations_for(self.configuration, 'a.a')
+ ret= rels.execute()
+ self.assertTrue(ret)
+
+ def test_not_has_ref(self):
+ factory = DummyRelationFactory()
+ # depends on c.a which has no value in conf
+ rels = factory.get_relations_for(self.configuration, 'b.a')
+ ret = rels.execute()
+ self.assertFalse(ret)
+
+ for rel in rels:
+ ip = rel.interpreter
+ self.assertTrue(ip.errors)
+ errors = ip.errors
+ self.assertTrue(errors.get('b.a'))
+
+ def test_not_has_ref_in_container(self):
+ factory = DummyRelationFactory()
+ rels = factory.get_relations_for(self.configuration, 'c.b')
+ ret = rels.execute()
+ self.assertFalse(ret)
+
+ def test_two_on_the_left(self):
+ factory = DummyRelationFactory()
+ rels = factory.get_relations_for(self.configuration, 'a.c')
+ ret = rels.execute()
+ self.assertTrue(ret)
+
+
+class TestASTInterpreter(unittest.TestCase):
+ def test_require(self):
+ ip = ASTInterpreter('a excludes b require 0')
+ ret = ip.eval()
+
+ def test_get_tokens(self):
+ self.assertEquals(get_tokens("foo=(2+1) * 3"),['foo','=','(','2','+','1',')','*','3'])
+ self.assertEquals(get_tokens("Arithmetic.MixedResult3 = (Arithmetic.Value2 / 2 + Arithmetic.Value1 * 9) - 7"),['Arithmetic.MixedResult3', '=', '(', 'Arithmetic.Value2', '/', '2', '+', 'Arithmetic.Value1', '*', '9', ')', '-', '7'])
+ print get_tokens(multilines)
+ self.assertEquals(len(get_tokens(multilines)),25)
+
+ def test_get_unindented_multiline_tokens(self):
+ self.assertEquals(
+ get_tokens("foo = 2+bar\nand foobar = 3 and\nfubar=4"),
+ ['foo', '=', '2', '+', 'bar', 'and', 'foobar', '=', '3', 'and', 'fubar', '=', '4'])
+
+ def test_get_tab_separated_tokens(self):
+ self.assertEquals(
+ get_tokens("foo\tconfigures\t\tbar\t=\t5"),
+ ['foo', 'configures', 'bar', '=', '5'])
+
+ def test_get_unicode_tokens(self):
+ self.assertEquals(
+ get_tokens(u'xÿz configures xzÿ = ÿxá'),
+ [u'xÿz', 'configures', u'xzÿ', '=', u'ÿxá'])
+
+ def test_get_unicode_tokens_2(self):
+ self.assertEquals(
+ get_tokens(u'ελληνικά configures ünicode = u"test string" + ελληνικά'),
+ [u'ελληνικά', 'configures', u'ünicode', '=', 'u"test string"', '+', u'ελληνικά'])
+
+ def test_get_unicode_tokens_3(self):
+ self.assertEquals(
+ get_tokens(u'oöoä äöoö oöo öoö äaäa'),
+ [u'oöoä', u'äöoö', u'oöo', u'öoö', u'äaäa'])
+
+ def test_get_unicode_tokens_4(self):
+ self.assertEquals(
+ get_tokens(u'ünicode.rêf1 require rêf2 . ελληνικά'),
+ [u'ünicode.rêf1', u'require', u'rêf2.ελληνικά'])
+
+ def test_get_unicode_tokens_multiline(self):
+ tokenstr = u"""
+ foo=(2+1) * 3
+ xÿz configures xzÿ = ÿxá
+ ελληνικά configures ünicode = u"test string" + ελληνικά"""
+ expected = [
+ 'foo', '=', '(', '2', '+', '1', ')', '*', '3',
+ u'xÿz', 'configures', u'xzÿ', '=', u'ÿxá',
+ u'ελληνικά', 'configures', u'ünicode', '=', 'u"test string"', '+', u'ελληνικά',
+ ]
+ actual = get_tokens(tokenstr)
+ self.assertEquals(actual, expected, '\n%r \n!= \n%r' % (actual, expected))
+
+ def test_multiline_string(self):
+ tokenstr = '''
+"""
+tes-
+ti
+"""
+ '''
+ expected = ['"""\ntes-\nti\n"""']
+ self.assertEquals(get_tokens(tokenstr), expected)
+
+ def test_syntax_error(self):
+ try:
+ ip = ASTInterpreter('a and and')
+ self.assertTrue(False)
+ except ParseException:
+ self.assertTrue(True)
+
+ def test_empty_expression(self):
+ expression = ''
+ ip = ASTInterpreter(expression)
+ result = ip.eval()
+ self.assertFalse(result)
+
+ def test_no_expression(self):
+ ip = ASTInterpreter()
+ result = ip.eval()
+ self.assertFalse(result)
+
+ try:
+ ip.create_ast(None)
+ self.assertFalse(True)
+ except ParseException:
+ self.assertTrue(True)
+
+ ip.create_ast('1 and 1')
+ result = ip.eval()
+ self.assertTrue(result)
+
+ def test_one_param_ops(self):
+ ip = ASTInterpreter('1 and truth 1')
+ result = ip.eval()
+ self.assertTrue(result)
+
+ ip.create_ast('1 and truth 0')
+ result = ip.eval()
+ self.assertFalse(result)
+
+ ip.create_ast(u'1 and truth not 0')
+ result = ip.eval()
+ self.assertTrue(result)
+
+ def test_infix_to_postfix(self):
+ expression = '1 and not 1'
+ ip = ASTInterpreter(expression)
+ self.assertEqual(ip.postfix_array, ['1', '1', 'not', 'and'])
+ self.assertFalse(ip.eval())
+
+ def test_infix_to_postfix_pars(self):
+ expression = '1 and ( 0 or 1 and 1 )'
+ ip = ASTInterpreter(expression)
+ self.assertEqual(ip.postfix_array, ['1', '0', '1', 'or', '1', 'and', 'and'])
+ self.assertTrue(ip.eval())
+
+ def test_not(self):
+ ip = ASTInterpreter(u'not 1',)
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'not 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast('not STRING_VALUE')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_not_with_multiple(self):
+ ip = ASTInterpreter(u'1 and not 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+ ip.create_ast(u'1 and not 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_and(self):
+ ip = ASTInterpreter(u'1 and 1 and 0')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'1 and 1 and 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ def test_nand(self):
+ ip = ASTInterpreter(u'1 nand 1 nand 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'1 nand 1 nand 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'1 nand 0 nand 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'0 nand 0 nand 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ def test_or(self):
+ ip = ASTInterpreter(u'1 or 1 or 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ def test_or_for_exclude(self):
+ """
+ On exclude case if OR returns True -> some element is selected
+ and the rule evaluation should fail, the exclude rule should
+ evaluate if PostfixRuleEngine.eval(expression) -> return False
+ """
+ ip = ASTInterpreter(u'1 or 1 or 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'1 or 1 or 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'1 or 0 or 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 or 1 or 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'1 or 0 or 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 or 0 or 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 or 0 or 0')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_nor(self):
+ ip = ASTInterpreter(u'1 nor 1 nor 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'1 nor 1 nor 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 nor 1 nor 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 nor 0 nor 0')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+
+ def test_xor(self):
+ ip = ASTInterpreter(u'1 xor 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'1 xor 0 xor 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ def test_eq_cmp(self):
+ ip = ASTInterpreter(u'1 == 0')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'1 == 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'DEFINED == DEFINED')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'DEFINED == UNDEFINED')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_neq_cmp(self):
+ ip = ASTInterpreter(u'1 != 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'1 != 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ def test_lt_cmp(self):
+ ip = ASTInterpreter(u'0 < 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'-1 < 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'-1 < -2')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'2 < 0')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_gt_cmp(self):
+ ip = ASTInterpreter(u'0 > -1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'2 > 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 > 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ ip.create_ast(u'-1 > 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_lte_cmp(self):
+ ip = ASTInterpreter(u'0 <= 1')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 <= 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'1 <= 0')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_gte_cmp(self):
+ ip = ASTInterpreter(u'1 >= 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 >= 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+ ip.create_ast(u'0 >= 1')
+ ret = ip.eval()
+ self.assertFalse(ret)
+
+ def test_extract_refs(self):
+ refs = ASTInterpreter.extract_refs('a.a and ( b.c and d.e )')
+ self.assertTrue('a.a' in refs)
+ self.assertTrue('b.c' in refs)
+ self.assertTrue('d.e' in refs)
+ self.assertTrue('and' not in refs)
+
+ def test_one_of(self):
+ """ Test for showing that relation one-of is basically "LEFT and R1 xor R2"
+ """
+ ip = ASTInterpreter(u'1 and 1 and 1 xor 0')
+ ret = ip.eval()
+ self.assertTrue(ret)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_rules_on_configuration.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_rules_on_configuration.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,277 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import operator as ops
+import unittest
+import sys, os
+import __init__
+import tokenize
+import StringIO
+
+from cone.public import api,exceptions, utils
+from cone.public.rules import ASTInterpreter, RelationContainerImpl
+from cone.public.rules import ParseException, DefaultContext, BaseRelation
+from cone.public import rules
+
+#### TEST RELATIONS ####
+
+AA_BA = 'a.a == "foo" requires b.b != 0'
+AB_BB = 'a.b configures b.b = a.b+":"+ "test"'
+BA_CA = 'b.a requires c.a and c.b and a.b'
+
+CB_DA = 'c.b requires d.a'
+DA_DB = 'd.a requires d.b'
+
+AC_AB_BA = 'a.c and a.a requires b.a'
+
+EA_FSTAR = 'e.a requires f.*'
+
+TEST_RELATIONS = {
+ 'a.a' : [AA_BA, 'a.a == "test" requires b.a'],
+ 'a.b' : [AB_BB],
+ 'a.c' : [AC_AB_BA],
+ 'b.a' : [BA_CA],
+ 'c.b' : [CB_DA],
+ 'd.a' : [DA_DB],
+ 'e.a' : [EA_FSTAR]
+}
+
+def get_test_configuration():
+ config = api.Configuration()
+ config.add_feature(api.Feature('a'))
+ config.add_feature(api.Feature('a'),'a')
+ config.add_feature(api.Feature('b'),'a')
+ config.add_feature(api.Feature('c'),'a')
+ config.add_feature(api.Feature('b'))
+ config.add_feature(api.Feature('a'),'b')
+ config.add_feature(api.Feature('b'),'b')
+ config.add_feature(api.Feature('c'))
+ config.add_feature(api.Feature('a'),'c')
+ config.add_feature(api.Feature('b'),'c')
+ config.add_feature(api.Feature('d'))
+ config.add_feature(api.Feature('a'),'d')
+ config.add_feature(api.Feature('b'),'d')
+ config.add_feature(api.Feature('e'))
+ config.add_feature(api.Feature('a'),'e')
+ dview = config.get_default_view()
+ dview.get_feature('a.a').set_value('test')
+ dview.get_feature('a.b').set_value('hey')
+ dview.get_feature('a.c').set_value(False)
+ dview.get_feature('b.a').set_value(True)
+ dview.get_feature('b.b').set_value(True)
+ dview.get_feature('c.a').set_value(True)
+ dview.get_feature('c.b').set_value(True)
+ dview.get_feature('d.a').set_value(False)
+ dview.get_feature('d.b').set_value(False)
+ return config
+
+class TestFactory():
+ def get_relations_for(self, configuration, ref):
+ rels = TEST_RELATIONS.get(ref)
+ if rels:
+ relation_container = RelationContainerImpl()
+ for rel in rels:
+ (left_expression,relation_name,right_expression) = parse_rule(rel)
+ relation = rules.RELATIONS.get(relation_name)(configuration, left_expression, right_expression)
+ relation_container.add_relation(relation)
+ propagated_relations = self.get_relations_for(configuration, right_expression)
+ if propagated_relations:
+ for relation in propagated_relations:
+ relation_container.add_relation(relation)
+ return relation_container
+ return None
+
+def parse_rule(rulestring):
+ """
+ Divide the given rule string into (left side, relation, right side) components.
+ @return: Triple (left side, relation, right side)
+ """
+ left_expression = ''
+ relation_name = None
+ right_expression = ''
+ for token in rules.get_tokens(rulestring):
+ if relation_name == None:
+ if token in rules.RELATIONS.keys():
+ relation_name = token
+ else:
+ left_expression += ' ' + token
+ else:
+ right_expression += ' ' + token
+
+ if relation_name == None:
+ raise exceptions.ParseError('invalid rule definition %s' % rulestring)
+
+ return (left_expression,relation_name,right_expression)
+
+class ConfigurationContext(DefaultContext):
+ def handle_terminal(self, expression):
+ try:
+ value = self.data.get_feature(expression).get_value()
+ if value != None:
+ #print "handle_terminal %s = %s" % (expression,value)
+ return value
+ else:
+ raise exceptions.NotBound('Feature %s has no value' % expression)
+ except exceptions.NotFound,e:
+ """ return the expression itself if it is not a fearef """
+ #print "handle_terminal constant %s" % (expression)
+ try:
+ return eval(expression)
+ except (NameError,SyntaxError), e:
+ return expression
+
+ def eval(self, ast, expression, value):
+ #print "expression %s = %s" % (expression,value)
+ pass
+
+class ConfigurationBaseRelation(BaseRelation):
+ def __init__(self, data, left, right):
+ self.context = ConfigurationContext(data)
+ super(ConfigurationBaseRelation, self).__init__(data, left, right)
+
+class RequireRelation(ConfigurationBaseRelation):
+ KEY = 'requires'
+ def __init__(self, data, left, right):
+ super(RequireRelation, self).__init__(data, left, right)
+ self.context = ConfigurationContext(data)
+
+class ConfigureRelation(ConfigurationBaseRelation):
+ KEY = 'configures'
+ def __init__(self, data, left, right):
+ super(ConfigureRelation, self).__init__(data, left, right)
+ self.context = ConfigurationContext(data)
+
+def handle_configure(self, left, right):
+ if left and right:
+ return True
+ elif not left:
+ return True
+ return False
+
+def handle_set(self, left, right):
+ left.set_value(right)
+
+class ConfigureExpression(rules.TwoOperatorExpression):
+ PRECEDENCE = rules.PRECEDENCES['RELATION_OPERATORS']
+ KEY = 'configures'
+ OP = handle_configure
+
+ def eval(self, context):
+ super(ConfigureExpression, self).eval(context)
+ if not self.value:
+ left_keys = []
+ for ref in self.ast.extract_refs(str(self.left)):
+ for key in context.get_keys(ref):
+ left_keys.append(key)
+
+ for key in left_keys:
+ self.ast.add_error(key, { 'error_string' : 'CONFIGURES right side value is "False"',
+ 'left_key' : key,
+ 'rule' : self.ast.expression
+ })
+ return self.value
+
+def handle_plus(self, a,b):
+ #print "%s adding a: %s to b: %s" % (self, a,b)
+ return a + b
+
+class ConcatExpression(rules.TwoOperatorExpression):
+ PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
+ KEY= '+'
+ OP = handle_plus
+
+
+class SetExpression(rules.TwoOperatorExpression):
+ PRECEDENCE = rules.PRECEDENCES['SET_OPERATORS']
+ KEY= '='
+ OP = handle_set
+
+ def eval(self, context):
+ try:
+ variable = context.data.get_feature(self.left.expression)
+ variable.set_value(self.right.eval(context))
+ return True
+ except exceptions.NotFound:
+ return False
+
+class TestRelations(unittest.TestCase):
+
+ def setUp(self):
+ self.configuration = get_test_configuration()
+
+ self.RELATIONS_BACKUP = rules.RELATIONS
+ self.OPERATORS_BACKUP = rules.OPERATORS
+ rules.RELATIONS = rules.RELATIONS.copy()
+ rules.OPERATORS = rules.OPERATORS.copy()
+ self.assertTrue(self.RELATIONS_BACKUP is not rules.RELATIONS)
+ self.assertTrue(self.OPERATORS_BACKUP is not rules.OPERATORS)
+
+ rules.RELATIONS[RequireRelation.KEY] = RequireRelation
+ rules.RELATIONS[ConfigureRelation.KEY] = ConfigureRelation
+ rules.OPERATORS[ConfigureExpression.KEY] = ConfigureExpression
+ rules.OPERATORS[ConcatExpression.KEY] = ConcatExpression
+ rules.OPERATORS[SetExpression.KEY] = SetExpression
+
+ def tearDown(self):
+ rules.RELATIONS = self.RELATIONS_BACKUP
+ rules.OPERATORS = self.OPERATORS_BACKUP
+
+ def test_has_ref(self):
+ """
+ Tests the relation and relation container
+ """
+ factory = TestFactory()
+ rels = factory.get_relations_for(self.configuration, 'a.a')
+ ret= rels.execute()
+ self.assertTrue(ret)
+
+ def test_has_ref(self):
+ """
+ Tests the relation and relation container
+ """
+ factory = TestFactory()
+ rels = factory.get_relations_for(self.configuration, 'a.a')
+ ret= rels.execute()
+ self.assertTrue(ret)
+
+ def test_not_has_ref(self):
+ factory = TestFactory()
+ # depends on c.a which has no value in conf
+ rels = factory.get_relations_for(self.configuration, 'b.a')
+ ret = rels.execute()
+ self.assertTrue(ret)
+
+ def test_not_has_ref_in_container(self):
+ factory = TestFactory()
+ rels = factory.get_relations_for(self.configuration, 'c.b')
+ ret = rels.execute()
+ self.assertFalse(ret)
+
+ def test_two_on_the_left(self):
+ factory = TestFactory()
+ rels = factory.get_relations_for(self.configuration, 'a.c')
+ ret = rels.execute()
+ self.assertTrue(ret)
+
+ def test_configure_right_side(self):
+ factory = TestFactory()
+ rels = factory.get_relations_for(self.configuration, 'a.b')
+ ret = rels.execute()
+ self.assertTrue(ret)
+ self.assertEquals(self.configuration.get_default_view().get_feature('b.b').get_value(),'hey:test')
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_rules_simplecondition.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_rules_simplecondition.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,133 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os
+import re
+import logging
+import __init__
+from cone.public import *
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestContext(object):
+ """ DefaultContext implements ConE specific context for handling rules
+ """
+ def __init__(self, data):
+ self.data = data
+
+ def eval(self, ast, expression, value):
+ pass
+
+ def get_keys(self, refs):
+ return ASTInterpreter.extract_refs(refs)
+
+ def get_children_for_reference(self, reference):
+ # implement ConE specific children expansion
+ pass
+
+ def handle_terminal(self, expression):
+ try:
+ m = re.match("\${(.*)}", expression)
+ if m:
+ return self.data[m.group(1)]
+ elif expression in ['true','1','True']:
+ return True
+ elif expression in ['false','0','False']:
+ return False
+ else:
+ return eval(expression)
+ except:
+ return expression
+
+class TestPluginCondition(unittest.TestCase):
+
+ def test_create_plugin_condition(self):
+ condition = rules.SimpleCondition("foo.bar", "True")
+
+ def test_create_plugin_and_eval_booleans(self):
+ context = TestContext(None)
+ condition = rules.SimpleCondition("1", "True")
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("0", True)
+ self.assertFalse(condition.eval(context))
+
+ def test_create_plugin_and_eval_integers(self):
+ context = TestContext(None)
+ condition = rules.SimpleCondition("1", "2")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("112", "2")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("2", "2")
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition(2, 2)
+ self.assertTrue(condition.eval(context))
+
+ def test_create_plugin_and_eval_string(self):
+ context = TestContext(None)
+ condition = plugin.rules.SimpleCondition("test", "foo")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("test", "")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("test foo", "test foo")
+ self.assertTrue(condition.eval(context))
+
+ def test_create_plugin_and_eval_data_reference(self):
+ context = TestContext({'test' : 1, 'foo' : 2, 'bar' : True})
+ condition = rules.SimpleCondition("${test}", 1)
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("${test}", False)
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("${test}", "${foo}")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("${test}", "${bar}")
+ self.assertTrue(condition.eval(context))
+
+ def test_create_plugin_and_eval_data_reference_on_generation_context(self):
+ context = plugin.GenerationContext()
+ context.configuration = api.Configuration()
+ context.configuration.add_feature(api.Feature("test"))
+ context.configuration.add_feature(api.Feature("stringsub"),"test")
+ context.configuration.add_feature(api.Feature("intsub"),"test")
+ condition = rules.SimpleCondition("${test}", None)
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("${test.stringsub}", "None")
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("${test.intsub}", "None")
+ self.assertTrue(condition.eval(context))
+ context.configuration.get_default_view().test.value = True
+ context.configuration.get_default_view().test.stringsub.value = "stringval"
+ context.configuration.get_default_view().test.intsub.value = 2
+ condition = rules.SimpleCondition("${test}", "true")
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("${test}", "false")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("${test.stringsub}", "tes")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("${test.stringsub}", "stringval")
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("${test.intsub}", "1")
+ self.assertFalse(condition.eval(context))
+ condition = rules.SimpleCondition("${test.intsub}", "2")
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("${test.intsub}", 2)
+ self.assertTrue(condition.eval(context))
+ condition = rules.SimpleCondition("${test.intsub}", 1)
+ self.assertFalse(condition.eval(context))
+ try:
+ condition = rules.SimpleCondition("${boo}", "false")
+ self.fail("access of non existing elements succeds?")
+ except:
+ pass
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_settings.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_settings.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,102 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import StringIO
+import sys,os
+import __init__
+
+from cone.public import api,exceptions,settings
+
+import ConfigParser
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+configdata = \
+'''
+[DEFAULT]
+output_root=output
+output_subdir=
+plugin_output=
+output=%(output_root)s/%(output_subdir)s/%(plugin_output)s
+
+plugin_targets = 'rofs2','rofs3'
+
+generate_targets = 'rofs3'
+generate_layers = -1
+generate_impls =
+
+
+[CRML]
+plugin_output=%(plugin_output)s/private/1234567
+tags={target : [%(plugin_targets)s]}
+
+[CONTENT]
+tags={target : ['rofs2','rofs3','uda']}
+
+[ROFS3]
+output_subdir=rofs3
+'''
+
+imagedefault = \
+'''
+[DEFAULT]
+subdir=content
+foobar=fs/content
+'''
+
+class TestConfigParser(unittest.TestCase):
+ def tearDown(self):
+ settings.SettingsFactory.clear()
+
+ def test_config_parser_from_string(self):
+ config = ConfigParser.ConfigParser()
+ config.readfp(StringIO.StringIO(configdata))
+ config.readfp(StringIO.StringIO(imagedefault))
+ self.assertEquals(config.get('ROFS3','output'),'output/rofs3/')
+ self.assertEquals(config.get('CRML','tags'),"{target : ['rofs2','rofs3']}")
+
+ def test_get_parser(self):
+ settings.SettingsFactory.defaultconfig = os.path.join(ROOT_PATH,'test_defaults.cfg')
+ s = settings.SettingsFactory.cone_parser()
+ cs = settings.ConeSettings(s)
+ self.assertEquals(s.get('DEFAULT','output'),'output//')
+
+ def test_cone_settings(self):
+ settings.SettingsFactory.defaultconfig = os.path.join(ROOT_PATH,'test_defaults.cfg')
+ s = settings.SettingsFactory.cone_parser()
+ cs = settings.ConeSettings(s)
+ self.assertEquals(cs.get('output'),'output//')
+ self.assertEquals(cs.get('foobar'),None)
+ self.assertEquals(cs.get('foobar', 'test'),'test')
+
+ def test_cone_settings_with_invalid_section(self):
+ settings.SettingsFactory.defaultconfig = os.path.join(ROOT_PATH,'test_defaults.cfg')
+ settings.SettingsFactory.configsettings = None
+ s = settings.SettingsFactory.cone_parser()
+ cs = settings.ConeSettings(s,'FOOBAR')
+ self.assertEquals(cs.get('output'),'output//')
+ self.assertEquals(cs.get('foobar'),None)
+ self.assertEquals(cs.get('foobar', 'test'),'test')
+ self.assertEquals(cs.get('output','',{'output_subdir':'content',
+ 'output_subdir':'content'}),'output/content/')
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_storage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_storage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,434 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test Respource
+"""
+import unittest
+import string
+import sys,os
+import pickle
+import __init__
+
+from cone.public import api, exceptions, utils
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+temp_dir = os.path.join(ROOT_PATH, "temp/storage")
+storage_path = os.path.join(temp_dir, "layertest.pk")
+
+class TestStorage(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_create_storage(self):
+ res = api.Storage("")
+ self.assertTrue(res)
+
+ def test_get_root(self):
+ path = os.path.join(temp_dir, "foo/faa.pk")
+ store = api.Storage.open(path,"w")
+ self.assertEquals(store.get_path(),path)
+
+ def test_set_path(self):
+ path = os.path.join(temp_dir, "foo/faa.pk")
+ store = api.Storage.open(path,"w")
+ self.assertEquals(store.get_path(),path)
+ store.set_current_path("faa")
+ self.assertEquals(store.get_current_path(),"faa")
+
+ def test_get_more_read(self):
+ storage = api.Storage("")
+ self.assertEquals(storage.get_mode("r"),storage.MODE_READ)
+ self.assertEquals(storage.get_mode("rb"),storage.MODE_READ)
+
+ def test_get_more_write(self):
+ storage = api.Storage("")
+ self.assertEquals(storage.get_mode("w"),storage.MODE_WRITE)
+ self.assertEquals(storage.get_mode("wb"),storage.MODE_WRITE)
+
+ def test_get_more_append(self):
+ storage = api.Storage("")
+ self.assertEquals(storage.get_mode("a"),storage.MODE_APPEND)
+ self.assertEquals(storage.get_mode("ab"),storage.MODE_APPEND)
+
+ def test_get_more_unknown(self):
+ storage = api.Storage("")
+ self.assertEquals(storage.get_mode("1"),storage.MODE_UNKNOWN)
+ self.assertEquals(storage.get_mode("2b"),storage.MODE_UNKNOWN)
+
+class TestStorageGeneric(unittest.TestCase):
+ def test_list_resources(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ self.assertEquals(store.list_resources(""), [])
+
+ def test_open_resource_nonexisting(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ try:
+ res = store.open_resource("test")
+ res.close()
+ self.fail("Opening non existing resource succeeds")
+ except exceptions.NotResource,e:
+ pass
+
+ def test_is_resource_nonexisting(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ self.assertFalse(store.is_resource("test"))
+
+ def test_open_resource_is_resource(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res = store.open_resource("test","w")
+ res.write("Testing writing more")
+ res.close()
+ self.assertTrue(store.is_resource('test'))
+
+ def test_open_resource_write_and_write(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res = store.open_resource("test","w")
+ res.write("Testing writing more")
+ res.close()
+ res = store.open_resource("test","w")
+ res.write("writing")
+ res.close()
+ self.assertEquals(store._get('test').data, 'writing')
+
+ def test_get_size_on_write_only_resource_fails(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res = store.open_resource("test","w")
+ res.write("Writing foobar")
+ self.assertRaises(exceptions.StorageException, res.get_size)
+ res.close()
+
+ def test_open_resource_and_get_size(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res = store.open_resource("test","w")
+ res.write("Writing foobar")
+ res.close()
+
+ res = store.open_resource("test","r")
+ self.assertEquals(res.get_size(), 14)
+ res.close()
+
+ def test_write_fails_on_read_mode(self):
+ store = api.Storage.open(storage_path, "w")
+ self.assertTrue(store)
+ res = store.open_resource("test","w")
+ res.write("Testing writing more")
+ res.close()
+ resr = store.open_resource("test","r")
+ try:
+ resr.write("Testing writing more")
+ resr.close()
+ self.fail("Writing succeeds on read mode?")
+ except exceptions.StorageException, e:
+ pass
+
+ def test_open_resource_append(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res = store.open_resource("test","a")
+ res.write("Testing append.\n")
+ res.close()
+ res = store.open_resource("test","a")
+ res.write("appending!")
+ res.close()
+ self.assertEquals(store.test.data, 'Testing append.\nappending!')
+
+ def test_open_multiple_no_close_and_write_closed(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test","a")
+ res1.write("Testing append.\n")
+ res1.close()
+ res2 = store.open_resource("test","a")
+ res2.write("appending!")
+ res2.close()
+ try:
+ res2.write("sss")
+ self.fail("writing on closed object succeeds?")
+ except ValueError:
+ pass
+ self.assertEquals(store.test.data, 'Testing append.\nappending!')
+
+ def test_open_many_to_one(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test/foo.txt","a")
+ res1.write("Testing\n")
+ res1.close()
+ res1 = store.open_resource("test/foo.txt","w")
+ res1.close()
+ self.assertEquals(store.list_resources('', True),['test/foo.txt'])
+
+ def test_open_many(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test/foo.txt","a")
+ res1.write("Testing\n")
+ res1.close()
+ res2 = store.open_resource("test/bar.txt","a")
+ res2.write("Writing bar!")
+ res2.close()
+ self.assertEquals(store.test.foo.data, 'Testing\n')
+ self.assertEquals(store.test.bar.data, 'Writing bar!')
+
+ def test_open_many_to_a_hierarchy_and_list_folders(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ root= store.open_resource("root.txt","a")
+ root.write("root\n")
+ root.close()
+ res1 = store.open_resource("test/foo.txt","a")
+ res1.write("Testing\n")
+ res1.close()
+ res2 = store.open_resource("test/bar.txt","a")
+ res2.write("Writing bar!")
+ res2.close()
+ self.assertEquals(store.list_resources('/'), ['root.txt'])
+ self.assertEquals(store.list_resources('/test'), ['test/bar.txt',
+ 'test/foo.txt'])
+ self.assertEquals(store.list_resources('/',True), ['root.txt',
+ 'test/bar.txt',
+ 'test/foo.txt'])
+
+ def test_open_resource_and_delete(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res = store.open_resource("test1.txt","a")
+ res.write("Testing append.\n")
+ res.close()
+ res = store.open_resource("test2.txt","w")
+ res.write("Testing append.\n")
+ res.close()
+ res = store.open_resource("test3.txt","w")
+ res.write("Testing append.\n")
+ res.close()
+ for res in store.list_resources(''):
+ store.delete_resource(res)
+ self.assertEquals(store.list_resources(''), [])
+
+ def test_open_resources_and_read(self):
+ store = api.Storage.open(storage_path,"w")
+ self.assertTrue(store)
+ res = store.open_resource("test1.txt","w")
+ res.write("Testing reading.\n")
+ res.close()
+ res = store.open_resource("test2.txt","w")
+ res.write("Testing reading.\n")
+ res.close()
+ res = store.open_resource("test3.txt","w")
+ res.write("Testing reading.\n")
+ res.close()
+ for res in store.list_resources(''):
+ res = store.open_resource(res)
+ self.assertEquals(res.read(), "Testing reading.\n")
+
+ def test_open_resources_and_save_and_dump(self):
+ temp_file = os.path.join(temp_dir, "FooStore.pk")
+ store = api.Storage.open(temp_file, "w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test1.txt","w")
+ res1.write("Testing reading.\n")
+ res2 = store.open_resource("test2.txt","w")
+ res2.write("Testing reading.\n")
+ res3 = store.open_resource("test3.txt","w")
+ res3.write("Testing reading.\n")
+ store.save()
+
+ def test_open_resources_and_load(self):
+ temp_file = os.path.join(temp_dir, "store.pk")
+ store = api.Storage.open(temp_file,"w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test1.txt","w")
+ res1.write("Testing reading.\n")
+ res2 = store.open_resource("test2.txt","w")
+ res2.write("Testing reading.\n")
+ res3 = store.open_resource("test3.txt","w")
+ res3.write("Testing reading.\n")
+ store.close()
+ store2 = api.Storage.open(temp_file)
+ self.assertEquals(store2.list_resources(''), ['test1.txt',
+ 'test2.txt',
+ 'test3.txt'])
+ self.assertEquals(store2.open_resource("test1.txt").read(),'Testing reading.\n')
+ self.assertEquals(store2.open_resource("test2.txt").read(),'Testing reading.\n')
+ self.assertEquals(store2.open_resource("test3.txt").read(),'Testing reading.\n')
+
+ def test_import_resources(self):
+ temp_file = os.path.join(temp_dir, "importsource.pk")
+ store = api.Storage.open(temp_file, "w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test1.txt","w")
+ res1.write("Testing reading.\n")
+ res2 = store.open_resource("test2.txt","w")
+ res2.write("Testing reading.\n")
+ res3 = store.open_resource("test3.txt","w")
+ res3.write("Testing reading.\n")
+ store.save()
+ res3.close()
+ store2 = api.Storage.open(temp_file, "w")
+ store2.import_resources(store.list_resources(''), store)
+ self.assertEquals(store2.open_resource("test1.txt").read(),store.open_resource('test1.txt').read())
+ self.assertEquals(store2.open_resource("test2.txt").read(),store.open_resource('test2.txt').read())
+ self.assertEquals(store2.open_resource("test3.txt").read(),store.open_resource('test3.txt').read())
+ store2.close()
+
+ def test_export_resources(self):
+ temp_file = os.path.join(temp_dir, "exportsource.pk")
+ store = api.Storage.open(temp_file, "w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test1.txt","w")
+ res1.write("Testing reading.\n")
+ res2 = store.open_resource("test2.txt","w")
+ res2.write("Testing reading.\n")
+ res3 = store.open_resource("test3.txt","w")
+ res3.write("Testing reading.\n")
+ store.save()
+ store2 = api.Storage.open(temp_file, "w")
+ store.export_resources(store.list_resources(''), store2)
+ res2 = store2.open_resource("test1.txt")
+ res1 = store.open_resource('test1.txt')
+ self.assertEquals(res1.read(),res2.read())
+ self.assertEquals(store2.open_resource("test2.txt").read(),store.open_resource('test2.txt').read())
+ self.assertEquals(store2.open_resource("test3.txt").read(),store.open_resource('test3.txt').read())
+ store2.close()
+
+ def test_export_modify_and_close_and_open(self):
+ temp_file = os.path.join(temp_dir, "exportsource.pk")
+ store = api.Storage.open(temp_file,"w")
+ self.assertTrue(store)
+ res1 = store.open_resource("test1.txt","w")
+ res1.write("Testing reading.\n")
+ res1.close()
+
+ res2 = store.open_resource("test2.txt","w")
+ res2.write("Testing reading.\n")
+ res3 = store.open_resource("test3.txt","w")
+ res3.write("Testing reading.\n")
+
+ res1 = store.open_resource("test1.txt","w")
+ res1.write("Testing reading too.\n")
+ res1.close()
+
+ store.close()
+
+ modified_temp_file = os.path.join(temp_dir, "modified.pk")
+ store2 = api.Storage.open(modified_temp_file, "w")
+ store.export_resources(store.list_resources(''), store2)
+ store2.delete_resource('test3.txt')
+ resr = store2.open_resource('test2.txt')
+ resw = store2.open_resource('test2.txt','w')
+ resw.write("Now this sould be different")
+ store2.close()
+ store3 = api.Storage.open(modified_temp_file)
+ self.assertEquals(store3.list_resources(''), ['test1.txt',
+ 'test2.txt'])
+ self.assertEquals(store3.open_resource("test2.txt").read(),'Now this sould be different')
+ self.assertEquals(store3.open_resource("test1.txt").read(),'Testing reading too.\n')
+
+
+ def test_get_path_set_path(self):
+ temp_file = os.path.join(temp_dir, "subpath.pk")
+ store = api.Storage.open(temp_file,"w")
+ self.assertEquals(store.get_path(),temp_file)
+ self.assertEquals(store.get_current_path(),"")
+ store.set_current_path("subdir")
+ self.assertEquals(store.get_current_path(),"subdir")
+
+ def test_set_path_open_resource(self):
+ temp_file = os.path.join(temp_dir, "subpath.pk")
+ if os.path.exists(temp_file): os.unlink(temp_file)
+
+ store = api.Storage.open(temp_file,"w")
+ self.assertEquals(store.get_path(),temp_file)
+ store.set_current_path("subdir")
+ self.assertEquals(store.get_current_path(),"subdir")
+ res = store.open_resource("foo.txt","w")
+ res.write("foo")
+ res.close()
+ self.assertEquals(store.list_resources(""), ["foo.txt"])
+ store.set_current_path("/")
+ self.assertEquals(store.list_resources("", True), ["subdir/foo.txt"])
+ store.close()
+ os.unlink(temp_file)
+
+ def test_create_folder(self):
+ temp_file = os.path.join(temp_dir, "subpath.pk")
+ store = api.Storage.open(temp_file,"w")
+ store.create_folder("subdir/test")
+ self.assertTrue(store.is_folder("subdir/test"))
+
+ def test_create_folder_and_delete_folder(self):
+ temp_file = os.path.join(temp_dir, "subpath.pk")
+ store = api.Storage.open(temp_file,"w")
+ store.create_folder("subdir/test")
+ self.assertTrue(store.is_folder("subdir/test"))
+ store.delete_folder("subdir/test")
+ self.assertFalse(store.is_folder("subdir/test"))
+ self.assertTrue(store.is_folder("subdir"))
+
+class TestFolder(unittest.TestCase):
+
+ def test_create_folder(self):
+ store = api.Storage.open(storage_path,"w")
+ layer = api.Folder(store, "foo")
+ self.assertTrue(layer)
+
+ def test_get_path(self):
+ store = api.Storage.open(storage_path,"w")
+ layer = api.Folder(store, "foo")
+ self.assertTrue(layer)
+ self.assertEquals(layer.get_current_path(),"foo")
+
+ def test_open_resource(self):
+ store = api.Storage.open(storage_path,"w")
+ layer = api.Folder(store, "foo")
+ self.assertTrue(layer)
+ res = layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_resources("", True),["confml/test.confml"])
+ self.assertEquals(store.list_resources("", True),["foo/confml/test.confml"])
+
+ def test_create_two_layers_and_open_resource(self):
+ store = api.Storage.open(storage_path,"w")
+ foo_layer = api.Folder(store, "foo")
+ bar_layer = api.Folder(store, "bar")
+ res = foo_layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = foo_layer.open_resource("root.confml","w")
+ res.close()
+ res = bar_layer.open_resource("confml/root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(foo_layer.list_resources("", True),['confml/test.confml', 'root.confml'])
+ self.assertEquals(store.list_resources("", True),['bar/confml/root.confml','foo/confml/test.confml','foo/root.confml'])
+
+ foo_layer.delete_resource("confml/test.confml")
+ self.assertEquals(foo_layer.list_resources("", True),["root.confml"])
+ self.assertEquals(store.list_resources("", True),["bar/confml/root.confml","foo/root.confml"])
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_utils.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,643 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import zipfile
+import unittest
+import string
+import token
+import sys,os,re
+import __init__
+
+from cone.public import utils, rules, api, exceptions
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.abspath(os.path.join(ROOT_PATH,'utils-testdata'))
+
+class T(object):
+ def __init__(self,str=""): self.str = str
+
+class TestResourceRefs(unittest.TestCase):
+ def test_join_two_refs(self):
+ self.assertEquals(utils.resourceref.join_refs(['foo/bar/test','fancy.ref']),'foo/bar/test/fancy.ref')
+ self.assertEquals(utils.resourceref.join_refs(['foo/bar/test','/absref/fancy.ref']),'/absref/fancy.ref')
+
+ def test_join_three_refs(self):
+ self.assertEquals(utils.resourceref.join_refs(['foo/bar/test','fancy/ref','test1.12']),'foo/bar/test/fancy/ref/test1.12')
+
+ def test_join_two_refs_with_empty_first_ref(self):
+ self.assertEquals(utils.resourceref.join_refs(['','fancy/ref']),'fancy/ref')
+
+ def test_join_two_refs_with_empty_last_ref(self):
+ self.assertEquals(utils.resourceref.join_refs(['fancy/ref','']),'fancy/ref/')
+
+ def test_join_two_refs_with_two_emtpy_refs(self):
+ self.assertEquals(utils.resourceref.join_refs(['','']),'')
+
+ def test_join_three_refs_with_empty(self):
+ self.assertEquals(utils.resourceref.join_refs(['foo/bar/test','','test1/12']),'foo/bar/test/test1/12')
+
+ def test_join_three_refs_with_extra_slashes(self):
+ self.assertEquals(utils.resourceref.join_refs(['foo/bar/test/','/','one/']),'/one/')
+
+ def test_join_three_refs_with_extra_slashes_and_begin_slash(self):
+ self.assertEquals(utils.resourceref.join_refs(['/foo/bar/test/','/','one/']),'/one/')
+
+ def test_filter_files(self):
+ filtered = utils.resourceref.filter_resources(['test.txt','foo.dat','teat/data/bar.confml'],"\.txt")
+ self.assertEquals(filtered[0],'test.txt')
+
+ def test_filter_files_confmls(self):
+ filtered = utils.resourceref.filter_resources(['test.txt','foo.confml','test/data/bar.confml'],"\.confml")
+ self.assertEquals(filtered[0],'foo.confml')
+
+ def test_neg_filter_resources(self):
+ filtered = utils.resourceref.neg_filter_resources(['test.txt','foo.dat','teat/data/bar.confml'],"\.txt")
+ self.assertEquals(filtered[0],'foo.dat')
+ self.assertEquals(filtered[1],'teat/data/bar.confml')
+
+ def test_filter_files_with_extension(self):
+ filtered = utils.resourceref.filter_resources(['test.txt','foo.dat','teat/data/bar.confml'],".*\.dat")
+ self.assertEquals(filtered[0],'foo.dat')
+
+ def test_neg_filter_resources(self):
+ filtered = utils.resourceref.neg_filter_resources(['/test/.svn/test.txt','.svn/test/foo.dat','teat/data/bar.confml'],"\.svn")
+ self.assertEquals(filtered[0],'teat/data/bar.confml')
+
+ def test_insert_begin_slash_without(self):
+ self.assertEquals(utils.resourceref.insert_begin_slash('data/folder/siitake.txt'),'/data/folder/siitake.txt')
+
+ def test_insert_begin_slash_with(self):
+ self.assertEquals(utils.resourceref.insert_begin_slash('/data/folder/siitake.txt'),'/data/folder/siitake.txt')
+
+ def test_remove_begin_slash_without(self):
+ self.assertEquals(utils.resourceref.remove_begin_slash('data/folder/siitake.txt'),'data/folder/siitake.txt')
+
+ def test_remove_beging_slash_with(self):
+ self.assertEquals(utils.resourceref.remove_begin_slash('/data/folder/siitake.txt'),'data/folder/siitake.txt')
+
+ def test_add_end_slash_without(self):
+ self.assertEquals(utils.resourceref.add_end_slash('data/folder'),'data/folder/')
+
+ def test_add_end_slash_with(self):
+ self.assertEquals(utils.resourceref.add_end_slash('data/folder/'),'data/folder/')
+
+ def test_remove_end_slash_without(self):
+ self.assertEquals(utils.resourceref.remove_end_slash('data/folder'),'data/folder')
+
+ def test_remove_end_slash_with(self):
+ self.assertEquals(utils.resourceref.remove_end_slash('/data/folder/'),'/data/folder')
+
+ def test_split_ref_with_empty_elem(self):
+ self.assertEquals(utils.resourceref.split_ref(''),[])
+
+ def test_split_ref_two_elems(self):
+ self.assertEquals(utils.resourceref.split_ref('aaa/bbb'),['aaa','bbb'])
+
+ def test_split_ref_two_elems_and_begin_slash(self):
+ self.assertEquals(utils.resourceref.split_ref('/aaa/bbb'),['aaa','bbb'])
+
+ def test_split_ref_two_elems_and_end_slash(self):
+ self.assertEquals(utils.resourceref.split_ref('aaa/bbb/'),['aaa','bbb'])
+
+ def test_psplit_ref_with_tree_elems(self):
+ self.assertEquals(utils.resourceref.psplit_ref('aaa/bbb/ccc.txt'),('aaa/bbb','ccc.txt'))
+
+ def test_psplit_ref_with_two_elems(self):
+ self.assertEquals(utils.resourceref.psplit_ref('aaa/bbb'),('aaa','bbb'))
+
+ def test_psplit_ref_with_one_elems(self):
+ self.assertEquals(utils.resourceref.psplit_ref('aaa.conf'),('','aaa.conf'))
+
+ def test_psplit_ref_with_empty_elem(self):
+ self.assertEquals(utils.resourceref.psplit_ref(''),('',''))
+
+ def test_norm_ref(self):
+ self.assertEquals(utils.resourceref.norm('dir/with/something/skeleton.txt'),
+ 'dir/with/something/skeleton.txt')
+
+ def test_norm_ref_with_begin_dot(self):
+ self.assertEquals(utils.resourceref.norm('./skeleton.txt'),
+ 'skeleton.txt')
+
+ def test_norm_ref_with_begin_dot(self):
+ self.assertEquals(utils.resourceref.norm('.svn'),
+ '.svn')
+
+ def test_norm_ref_with_empty_string(self):
+ self.assertEquals(utils.resourceref.norm(''),
+ '')
+
+ def test_norm_ref_with_backslash(self):
+ self.assertEquals(utils.resourceref.norm('dir\\with\\something\\skeleton.txt'),
+ 'dir/with/something/skeleton.txt')
+
+ def test_norm_ref_with_backslash_and_forward_slash(self):
+ self.assertEquals(utils.resourceref.norm('dir\\with/something\\skeleton.txt'),
+ 'dir/with/something/skeleton.txt')
+
+ def test_norm_ref_with_begin_slash(self):
+ self.assertEquals(utils.resourceref.norm('/dir/with/something\\skeleton.txt'),
+ '/dir/with/something/skeleton.txt')
+
+ def test_norm_ref_with_begin_backslash(self):
+ self.assertEquals(utils.resourceref.norm('\\dir\\with\\something\\skeleton.txt'),
+ '/dir/with/something/skeleton.txt')
+
+ def test_norm_ref_with_end_slash(self):
+ self.assertEquals(utils.resourceref.norm('/dir/with/something/'),
+ '/dir/with/something')
+
+ def test_norm_ref_with_end_backslash(self):
+ self.assertEquals(utils.resourceref.norm('dir/with/something\\'),
+ 'dir/with/something')
+
+ def test_norm_ref_with_spaces(self):
+ self.assertEquals(utils.resourceref.norm('dir/with/some thing/some.txt'),
+ 'dir/with/some thing/some.txt')
+
+ def test_norm_ref_with_spaces_and_hyphens(self):
+ self.assertEquals(utils.resourceref.norm('"dir/with/some thing/some.txt"'),
+ 'dir/with/some thing/some.txt')
+
+ def test_norm_ref_with_spaces_and_hyphens_and_begin_slash(self):
+ self.assertEquals(utils.resourceref.norm('"/dir/with/some thing/some.txt"'),
+ '/dir/with/some thing/some.txt')
+
+ def test_replace_dir_part(self):
+ filename = utils.resourceref.replace_dir('dir/to/replace/with/something/skeleton.txt',
+ 'dir/to\\replace',
+ 'somethingelse/123/')
+ self.assertEquals(filename,'somethingelse/123/with/something/skeleton.txt')
+
+ def test_replace_dir_part_with_one_part(self):
+ filename = utils.resourceref.replace_dir('dir/to/replace/with/dir/dir.txt',
+ 'dir',
+ 'somethingelse/123/')
+ self.assertEquals(filename,'somethingelse/123/to/replace/with/dir/dir.txt')
+
+ def test_replace_dir_part_with_empty_target(self):
+ filename = utils.resourceref.replace_dir('dir/to/replace/with/dir/dir.txt',
+ 'dir',
+ '')
+ self.assertEquals(filename,'to/replace/with/dir/dir.txt')
+
+ def test_replace_dir_part_with_no_match(self):
+ filename = utils.resourceref.replace_dir('foo\\skeleton.txt',
+ 'dir/to\\replace',
+ 'somethingelse/123/')
+ self.assertEquals(filename,'foo/skeleton.txt')
+
+ def test_replace_dir_part_with_begin_slash(self):
+ filename = utils.resourceref.replace_dir('dir/to/replace/with/dir/dir.txt',
+ 'dir/to/replace',
+ '/epoc32/testing')
+ self.assertEquals(filename,'/epoc32/testing/with/dir/dir.txt')
+
+ def test_replace_dir_with_match(self):
+ filename = utils.resourceref.replace_dir('foo/test',
+ 'foo/test',
+ '')
+ self.assertEquals(filename,'')
+
+ def test_replace_dir_from_empty(self):
+ filename = utils.resourceref.replace_dir('foo/test',
+ '',
+ 'output/bar')
+ self.assertEquals(filename,'output/bar/foo/test')
+
+ def test_remove_ext(self):
+ self.assertEquals(utils.resourceref.remove_ext('fii/faa/foo.confml'),'fii/faa/foo')
+
+ def test_remove_ext_from_dot_beginning_file(self):
+ self.assertEquals(utils.resourceref.remove_ext('.metadata'),'.metadata')
+
+ def test_remove_ext_from_file_without_ext(self):
+ self.assertEquals(utils.resourceref.remove_ext('fii/faa/foo'),'fii/faa/foo')
+
+ def test_remove_ext_from_file_without_path(self):
+ self.assertEquals(utils.resourceref.remove_ext('fii.faa.foo'),'fii.faa')
+
+ def test_get_ext(self):
+ self.assertEquals(utils.resourceref.get_ext('fii/faa/foo.confml'),'confml')
+
+ def test_get_ext_without_ext(self):
+ self.assertEquals(utils.resourceref.get_ext('fii/faa/foo'),'')
+
+ def test_get_filename(self):
+ self.assertEquals(utils.resourceref.get_filename('fii/faa/foo.confml'),'foo.confml')
+
+ def test_get_filename_without_filename(self):
+ self.assertEquals(utils.resourceref.get_filename('fii/faa/'),'')
+
+ def test_get_filename_with_onepart(self):
+ self.assertEquals(utils.resourceref.get_filename('fii'),'fii')
+
+ def test_get_path(self):
+ self.assertEquals(utils.resourceref.get_path('fii/faa/foo.confml'),'fii/faa')
+
+ def test_get_path_without_filename(self):
+ self.assertEquals(utils.resourceref.get_path('fii/faa/'),'fii/faa')
+
+ def test_get_path_with_onepart(self):
+ self.assertEquals(utils.resourceref.get_path('fii'),'')
+
+ def test_to_dottedref(self):
+ self.assertEquals(utils.resourceref.to_dottedref('fii/faa/foo.confml'),'fii_faa_foo')
+
+ def test_to_dottedref_from_single_elem(self):
+ self.assertEquals(utils.resourceref.to_dottedref('fii'),'fii')
+
+ def test_to_dottedref_from_dotted(self):
+ self.assertEquals(utils.resourceref.to_dottedref('fii.faa.foo'),'fii.faa')
+
+ def test_to_dottedref_with_ext(self):
+ self.assertEquals(utils.resourceref.to_dottedref('.metadata'),'metadata')
+
+ def test_to_objref_dotted_start(self):
+ self.assertEquals(utils.resourceref.to_objref('../foo/bar/test.confml'),'____foo__bar__test_confml')
+
+ def test_to_objref_dot_in_name_start(self):
+ self.assertEquals(utils.resourceref.to_objref('/foo.bar/test.confml'),'_foo_bar_test_confml')
+
+ def test_to_objref_number_in_name_start(self):
+ self.assertEquals(utils.resourceref.to_objref('_1.0.test_one'),'_1_0_test_one')
+ self.assertEquals(utils.resourceref.to_objref('0.test_one'),'_0_test_one')
+ self.assertEquals(utils.resourceref.to_objref('1.0.test_one'),'_1_0_test_one')
+
+ def test_to_objref_unicode(self):
+ self.assertEquals(utils.resourceref.to_objref(u'fooäbar'),'foo_bar')
+ self.assertEquals(utils.resourceref.to_objref(u'foo:bar-testöne'),'foo_bar_test_ne')
+ self.assertEquals(utils.resourceref.to_objref('foo1.1test.confml'),'foo1_1test_confml')
+ self.assertEquals(utils.resourceref.to_objref('sub:417-48964:_hw_drv:_display_driver_common_features_-_thermal_event_handling_in_rdisplaykernel_and_thermal_management_for_display_module_behind_feature_flag'),
+ 'sub_417_48964__hw_drv__display_driver_common_features___thermal_event_handling_in_rdisplaykernel_and_thermal_management_for_display_module_behind_feature_flag')
+
+ def test_to_objref_dot_in_name_start(self):
+ self.assertEquals(utils.resourceref.to_objref('/foo.bar/test.confml'),'__foo_bar__test_confml')
+
+ def test_to_hash_dotted_start(self):
+ self.assertEquals(utils.resourceref.to_hash('../foo/bar/test.confml'),'0x5a063087')
+ self.assertEquals(utils.resourceref.to_hash('../foo/bar/test.confml'),'0x5a063087')
+
+ def test_to_hash(self):
+ self.assertEquals(utils.resourceref.to_hash('../fo.o/number.txt'),'-0x1b381b13')
+
+ def test_to_dref(self):
+ self.assertEquals(utils.resourceref.to_dref('fii/faa/foo.confml'),'fii.faa.foo')
+
+ def test_to_dref_with_ext(self):
+ self.assertEquals(utils.resourceref.to_dref('.metadata'),'metadata')
+
+ def test_to_dref_from_single_elem(self):
+ self.assertEquals(utils.resourceref.to_dref('fii'),'fii')
+
+ def test_to_dref_from_dotted(self):
+ self.assertEquals(utils.resourceref.to_dref('fii.faa.foo'),'fii.faa')
+
+class TestUtils(unittest.TestCase):
+ def test_distinct_array_with_single_values(self):
+ self.assertEquals(utils.distinct_array(['1','2','1','1']),['1','2'])
+
+ def test_distinct_array_with_single_values(self):
+ self.assertEquals(utils.distinct_array(['1','2','3','1','2','4']),['1','2','3','4'])
+
+ def test_list_files_from_testdata(self):
+ files = utils.list_files(testdata)
+ self.assertTrue(files[0].endswith('scrot.txt'))
+ self.assertTrue(files[1].endswith('test.txt'))
+
+ def test_list_files_from_current_dir(self):
+ files = utils.list_files('.')
+ self.assertTrue(len(files)>0)
+
+ def test_pathmatch_with_same_path(self):
+ self.assertEquals(utils.pathmatch('test.foo','test.foo'),True)
+
+ def test_pathmatch_with_diff_path(self):
+ self.assertEquals(utils.pathmatch('test.bar','test.foo'),False)
+
+ def test_pathmatch_with_star(self):
+ self.assertEquals(utils.pathmatch('test.foo.*','test.foo.bar'),True)
+
+ def test_pathmatch_with_star(self):
+ self.assertEquals(utils.pathmatch('test.foo.*','test.foo.bar.fiba'),False)
+
+ def test_pathmatch_with_twostar(self):
+ self.assertEquals(utils.pathmatch('test.foo.**','test.foo.bar.fiba'),True)
+
+ def test_filter_objs_ref(self):
+ obj = T("com.nokia.foo.bar")
+ filters = []
+ filters.append(lambda x: re.match(".*nokia.*", x.str))
+ self.assertEquals(utils.filter(obj,filters),True)
+
+ def test_filter_objs_ref_not(self):
+ obj = T("foo.bar")
+ filters = []
+ filters.append(lambda x: re.match("foo$", x.str))
+ self.assertEquals(utils.filter(obj,filters),False)
+
+ def test_filter_objs_type(self):
+ obj = T()
+ filters = []
+ filters.append(lambda x: isinstance(x,T))
+ self.assertEquals(utils.filter(obj,filters),True)
+
+ def test_filter_objs_type_not(self):
+ class F(object): pass
+ obj = T()
+ filters = []
+ filters.append(lambda x: isinstance(x,F))
+ self.assertEquals(utils.filter(obj,filters),False)
+
+class TestDottedRefs(unittest.TestCase):
+ def test_join_two_refs(self):
+ self.assertEquals(utils.dottedref.join_refs(['foo.bar.test','fancy.ref']),'foo.bar.test.fancy.ref')
+
+ def test_join_three_refs(self):
+ self.assertEquals(utils.dottedref.join_refs(['foo.bar.test','fancy.ref','test1.12']),'foo.bar.test.fancy.ref.test1.12')
+
+ def test_join_two_refs_with_empty_first_ref(self):
+ self.assertEquals(utils.dottedref.join_refs(['','fancy.ref']),'fancy.ref')
+
+ def test_join_two_refs_with_empty_last_ref(self):
+ self.assertEquals(utils.dottedref.join_refs(['fancy.ref','']),'fancy.ref')
+
+ def test_join_two_refs_with_two_emtpy_refs(self):
+ self.assertEquals(utils.dottedref.join_refs(['','']),'')
+
+ def test_join_three_refs_with_empty(self):
+ self.assertEquals(utils.dottedref.join_refs(['foo.bar.test','','test1.12']),'foo.bar.test.test1.12')
+
+ def test_split_ref_with_tree_elems(self):
+ self.assertEquals(utils.dottedref.split_ref('aaa.bbb.ccc'),['aaa','bbb','ccc'])
+
+ def test_split_ref_with_empty_elem(self):
+ self.assertEquals(utils.dottedref.split_ref(''),[])
+
+ def test_split_ref_with_empty_elem_between(self):
+ self.assertEquals(utils.dottedref.split_ref('aaa..bbb'),['aaa','bbb'])
+
+ def test_psplit_ref_with_tree_elems(self):
+ self.assertEquals(utils.dottedref.psplit_ref('aaa.bbb.ccc'),('aaa.bbb','ccc'))
+
+ def test_psplit_ref_with_two_elems(self):
+ self.assertEquals(utils.dottedref.psplit_ref('aaa.bbb'),('aaa','bbb'))
+
+ def test_psplit_ref_with_one_elems(self):
+ self.assertEquals(utils.dottedref.psplit_ref('aaa'),('','aaa'))
+
+ def test_psplit_ref_with_empty_elem(self):
+ self.assertEquals(utils.dottedref.psplit_ref(''),('',''))
+
+ def test_ref2filter_with_one_elem(self):
+ self.assertEquals(utils.dottedref.ref2filter('test'),'test$')
+
+ def test_ref2filter_with_two_elems(self):
+ self.assertEquals(utils.dottedref.ref2filter('test.foo'),'test\.foo$')
+
+ def test_ref2filter_with_three_elems(self):
+ self.assertEquals(utils.dottedref.ref2filter('test.foo.bar'),'test\.foo\.bar$')
+
+ def test_ref2filter_with_one_star(self):
+ self.assertEquals(utils.dottedref.ref2filter('*'),'[^\.]*$')
+
+ def test_ref2filter_with_two_elems_one_star(self):
+ self.assertEquals(utils.dottedref.ref2filter('test.foo.*'),'test\.foo\.[^\.]*$')
+
+ def test_ref2filter_with_two_elems_two_stars(self):
+ self.assertEquals(utils.dottedref.ref2filter('test.foo.*'),'test\.foo\.[^\.]*$')
+
+ def test_remove_extension(self):
+ self.assertEquals(utils.dottedref.remove_last('fii/foo.dat'),'fii/foo')
+
+ def test_remove_last_elem(self):
+ self.assertEquals(utils.dottedref.remove_last('fii.foo.faa.dat'),'fii.foo.faa')
+
+ def test_remove_last_elem_from_single(self):
+ self.assertEquals(utils.dottedref.remove_last('fii'),'fii')
+
+ def test_get_last_elem_from_single(self):
+ self.assertEquals(utils.dottedref.get_last('fii'),'fii')
+
+ def test_get_last_elem_from_empty(self):
+ self.assertEquals(utils.dottedref.get_last(''),'')
+
+ def test_get_last_elem_from_multi(self):
+ self.assertEquals(utils.dottedref.get_last('fii.faa.foo'),'foo')
+
+ def test_remove_begin_dot_without(self):
+ self.assertEquals(utils.dottedref.remove_begin_dot('data.folder.siitake'),
+ 'data.folder.siitake')
+
+ def test_remove_beging_dot_with(self):
+ self.assertEquals(utils.dottedref.remove_begin_dot('.data.folder.siitake'),
+ 'data.folder.siitake')
+
+ def test_get_list_index(self):
+ self.assertEquals(utils.dottedref.get_index('data[0]'),0)
+
+ def test_get_list_with_long_index(self):
+ self.assertEquals(utils.dottedref.get_index('data[123]'),123)
+
+ def test_get_list_index_with_no_index(self):
+ self.assertEquals(utils.dottedref.get_index('data'),None)
+
+ def test_get_name_with_index(self):
+ self.assertEquals(utils.dottedref.get_name('data[0]'),'data')
+
+ def test_get_name_normal(self):
+ self.assertEquals(utils.dottedref.get_name('data'),'data')
+
+ def test_extract_delimited_tokens(self):
+ def check(expected, string, delimiters=None):
+ if delimiters != None: actual = utils.extract_delimited_tokens(string, delimiters)
+ else: actual = utils.extract_delimited_tokens(string)
+ self.assertEquals(expected, actual)
+
+ check([], '')
+ check(['x'], '${x}')
+ check(['x'], '@{x}', delimiters=('@{', '}'))
+ check(['my.ref1', 'my.ref2'],"test1 ${my.ref1} test2 ${ my.ref1 } ${my.ref2}")
+ check(['my.ref1', 'my\nmultiline\nref'],"test1 ${my.ref1} test2 ${ my.ref1 } ${my\nmultiline\nref}")
+ check(['my.ref1', 'my.ref2', u'????????.????????'], u"test1 ${my.ref1} test2 ${ my.ref2 } ${????????.????????}")
+
+ def test_extract_delimited_token_tuples(self):
+ def check(expected, string, delimiters=None):
+ if delimiters != None: actual = utils.extract_delimited_token_tuples(string, delimiters)
+ else: actual = utils.extract_delimited_token_tuples(string)
+ self.assertEquals(expected, actual)
+
+ check([], '')
+ check([('x', '${x}')], '${x}')
+ check([('x', '@{x}')], '@{x}', delimiters=('@{', '}'))
+ check([('my.ref1', '${my.ref1}'), ('my.ref1', '${ my.ref1 }'), ('my.ref2', '${my.ref2}')],
+ "test1 ${my.ref1} test2 ${ my.ref1 } ${my.ref2} yeah ${my.ref2}")
+ check([('my.ref1', '${my.ref1}'), ('my.ref1', '${ my.ref1 }'), ('my\nmultiline\nref', '${my\nmultiline\nref}')],
+ "test1 ${my.ref1} test2 ${ my.ref1 } ${my\nmultiline\nref}")
+ check([('my.ref1', '${my.ref1}'), ('my.ref2', '${ my.ref2 }'), (u'????????.????????', u'${????????.????????}')],
+ u"test1 ${my.ref1} test2 ${ my.ref2 } ${????????.????????}")
+
+ def test_expand_delimited_tokens(self):
+ def check(expected, string, delimiters=None):
+ def expand(ref, index):
+ return "<%d: %s>" % (index, ref)
+ if delimiters != None: actual = utils.expand_delimited_tokens(string, expand, delimiters)
+ else: actual = utils.expand_delimited_tokens(string, expand)
+ self.assertEquals(expected, actual)
+
+ check('test', 'test')
+ check('<0: x>', '${x}')
+ check('<0: x>', '@{x}', delimiters=('@{', '}'))
+ check('<0: x> <1: y> <0: x>', '${x} ${y} ${ x }')
+ check(u'<0: my.ref1> test <1: ????????.????????>', u'${ my.ref1 } test ${????????.????????}')
+ check('<0: my.ref1> test <1: my\nmultiline\nref>', '${ my.ref1} test ${my\nmultiline\nref}')
+
+ def test_expand_refs_by_default_view(self):
+ VALUES = {'Test.Color' : 'brown',
+ 'Test.Animal1': 'fox',
+ 'Test.Animal2': 'dog'}
+ class DummyFeature(object):
+ def __init__(self, ref):
+ self.ref = ref
+ def get_original_value(self):
+ return VALUES[self.ref]
+ class DummyDefaultView(object):
+ def get_feature(self, ref):
+ if ref in VALUES: return DummyFeature(ref)
+ else: raise exceptions.NotFound()
+ dview = DummyDefaultView()
+
+ result = utils.expand_refs_by_default_view(
+ "The quick ${Test.Color} ${Test.Animal1} jumps over the lazy ${Test.Animal2}.",
+ dview)
+ self.assertEquals(result, "The quick brown fox jumps over the lazy dog.")
+
+ # Test expanding with a non-existent ref
+ result = utils.expand_refs_by_default_view(
+ "The quick ${Test.Color} ${Test.Foo} jumps over the lazy ${Test.Animal2}.",
+ dview)
+ self.assertEquals(result, "The quick brown jumps over the lazy dog.")
+
+ # Test expanding with a non-existent ref and a custom default value
+ result = utils.expand_refs_by_default_view(
+ "The quick ${Test.Color} ${Test.Foo} jumps over the lazy ${Test.Animal2}.",
+ dview,
+ default_value_for_missing = 'giraffe')
+ self.assertEquals(result, "The quick brown giraffe jumps over the lazy dog.")
+
+
+class TestUtilsSubclasses(unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def test_all_subclasses_with_none(self):
+ class base(object): pass
+ classnames = utils.all_subclasses(base)
+ self.assertEquals(len(classnames),0)
+
+ def test_all_subclasses_class_tree(self):
+ class base(object): pass
+ class class1(base): pass
+ class class2(base): pass
+ class class12(class1): pass
+ class class123(class2): pass
+ classnames = utils.all_subclasses(base)
+ self.assertEquals(len(classnames),4)
+
+class TestUtilsDataMapRef(unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def test_get_feature_ref(self):
+ map = "foo/bar[@key='key 1']"
+ ref = utils.DataMapRef.get_feature_ref(map)
+ self.assertEquals(ref,'foo/bar')
+
+ def test_get_key_value(self):
+ map = "foo/bar[@key='key 1']"
+ value = utils.DataMapRef.get_key_value(map)
+ self.assertEquals(value,'key 1')
+
+
+class TestMakeList(unittest.TestCase):
+ def test_get_list_string(self):
+ self.assertEquals(utils.get_list('test'), ['test'])
+
+ def test_get_list_from_list(self):
+ self.assertEquals(utils.get_list(['test']), ['test'])
+
+ def test_get_list_from_list2(self):
+ self.assertEquals(utils.get_list(['test','test2']), ['test','test2'])
+
+ def test_is_list(self):
+ self.assertEquals(utils.is_list(['test','test2']), True)
+
+ def test_is_list_false(self):
+ self.assertEquals(utils.is_list('test'), False)
+
+ def test_add_list_with_list(self):
+ self.assertEquals(utils.add_list(['test','test2'], 'foo'), ['test','test2','foo'])
+
+ def test_add_list_with_none(self):
+ self.assertEquals(utils.add_list([], 'foo'), ['foo'])
+
+ def test_add_list_with_string(self):
+ self.assertEquals(utils.add_list('bar', 'foo'), ['bar','foo'])
+
+ def test_add_list_with_string2(self):
+ self.assertEquals(utils.add_list(['bar','test'], 'foo'), ['bar','test','foo'])
+
+ def test_prepend_list_with_none(self):
+ self.assertEquals(utils.prepend_list([], 'foo'), ['foo'])
+
+ def test_prepend_string_with_string(self):
+ self.assertEquals(utils.prepend_list('bar', 'foo'), ['foo','bar'])
+
+ def test_prepend_list_with_string(self):
+ self.assertEquals(utils.prepend_list(['bar','test'], 'foo'), ['foo','bar','test'])
+
+from cone.confml import model as confmlmodel
+
+class TestModelGetters(unittest.TestCase):
+ def test_get_module_specific_class(self):
+ cls = utils.get_class(confmlmodel,api.Configuration)
+ self.assertEquals(cls, confmlmodel.ConfmlConfiguration)
+
+ def test_get_module_specific_class_with_None_model(self):
+ cls = utils.get_class(None,api.Configuration)
+ self.assertEquals(cls, api.Configuration)
+
+class TestXmlUtilFunctions(unittest.TestCase):
+ def test_split_tag_namespace(self):
+ self.assertEquals(
+ utils.xml.split_tag_namespace("test"),
+ (None, 'test'))
+
+ self.assertEquals(
+ utils.xml.split_tag_namespace("{http://www.test.com/xml/1}test"),
+ ('http://www.test.com/xml/1', 'test'))
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_valueset.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_valueset.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,129 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test sets
+"""
+import unittest
+import sets
+import sys
+import os
+import __init__
+
+from cone.public import api,exceptions,utils
+
+
+class TestOption(unittest.TestCase):
+ def test_create_option(self):
+ elem = api.Option('test','123')
+ self.assertTrue(elem)
+ self.assertTrue(elem.get_name(),'test')
+ self.assertTrue(elem.get_value(),'123')
+
+ def test_option_compare(self):
+ elem1 = api.Option('test','1')
+ elem2 = api.Option('foo','2')
+ elem3 = api.Option('test','3')
+ self.assertFalse(elem1==elem2)
+ self.assertFalse(elem1==elem3)
+ self.assertTrue(elem1=='opt_value_1')
+ self.assertTrue(elem2=='opt_value_2')
+ self.assertTrue('opt_value_2' == elem2)
+
+class TestSets(unittest.TestCase):
+
+ def test_create_set(self):
+ ss = api.ValueSet([1,3,4])
+ self.assertTrue(1 in ss)
+ self.assertFalse(2 in ss)
+ self.assertTrue(3 in ss)
+ self.assertTrue(4 in ss)
+ self.assertFalse(5 in ss)
+
+ def test_create_set_with_range(self):
+ r = range(0,100000)
+ ss = api.ValueSet(r)
+ for i in r:
+ self.assertTrue(i in ss)
+ self.assertFalse(12345678 in ss)
+ self.assertFalse(-1 in ss)
+ self.assertFalse('test' in ss)
+
+ def test_set_union(self):
+ ss1 = api.ValueSet([1,3,4])
+ ss2 = api.ValueSet([2,5,6])
+ ss3 = ss1.union(ss2)
+ self.assertFalse(0 in ss3)
+ self.assertTrue(1 in ss3)
+ self.assertTrue(2 in ss3)
+ self.assertTrue(3 in ss3)
+ self.assertTrue(4 in ss3)
+ self.assertTrue(5 in ss3)
+ self.assertTrue(6 in ss3)
+
+ def test_set_intersection(self):
+ ss1 = api.ValueSet([1,2,3,4])
+ ss2 = api.ValueSet([2,5,6])
+ ss3 = ss1.intersection(ss2)
+ self.assertFalse(0 in ss3)
+ self.assertFalse(1 in ss3)
+ self.assertTrue(2 in ss3)
+ self.assertFalse(3 in ss3)
+ self.assertFalse(4 in ss3)
+ self.assertFalse(5 in ss3)
+ self.assertFalse(6 in ss3)
+
+
+class TestRange(unittest.TestCase):
+ def test_create_integer_range(self):
+ r= api.ValueRange(1,100)
+ self.assertTrue(1 in r)
+ self.assertTrue(2 in r)
+ self.assertTrue(3 in r)
+ self.assertTrue(4 in r)
+ self.assertFalse(0 in r)
+ self.assertFalse(101 in r)
+
+class TestRegexp(unittest.TestCase):
+ def test_create_regexp(self):
+ r= api.ValueRe('.*')
+ self.assertTrue('test' in r)
+ self.assertTrue('foo.foo' in r)
+ self.assertTrue('haahiis' in r)
+ self.assertTrue('1235' in r)
+
+ def test_create_regexp_allows_only_letters(self):
+ r= api.ValueRe('^[A-Za-z]*$')
+ self.assertTrue('test' in r)
+ self.assertFalse('foo.foo' in r)
+ self.assertTrue('haahiis' in r)
+ self.assertFalse('1235' in r)
+ self.assertTrue('Haaa' in r)
+
+ def test_create_regexp_allows_windows_drive(self):
+ r= api.ValueRe('^[A-Za-z]:$')
+ self.assertTrue('C:' in r)
+ self.assertFalse('foo.foo' in r)
+ self.assertTrue('h:' in r)
+ self.assertFalse('1235' in r)
+ self.assertFalse('Haaa' in r)
+
+ def test_create_regexp_allows_windows_path(self):
+ r= api.ValueRe('^[:\\\\A-Za-z1-9_\.]*$')
+ #self.assertTrue('C:' in r)
+ self.assertTrue('foo.foo' in r)
+ self.assertTrue('X:\\aaa\\bbb\ccc' in r)
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_views.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_views.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,208 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public import api,exceptions,utils
+
+class TestViews(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_create_view(self):
+ view = api.View("view1")
+ self.assertTrue(view)
+ self.assertTrue(view.ref, "view1")
+
+ def test_view_add(self):
+ view = api.View("view1")
+ view._add(api.Group("Test"))
+ self.assertEquals(view._list(),['Test'])
+
+# def test_view_add_child_incorrect_class(self):
+# view = api.View("view1")
+# try:
+# view._add(api.Feature("Test"))
+# self.fail("Adding incorrect class succeeds!")
+# except exceptions.IncorrectClassError,e:
+# pass
+
+# def test_group_add_child_incorrect_class(self):
+# group = api.Group("Group")
+# try:
+# group._add(api.Feature("Test"))
+# self.fail("Adding incorrect class succeeds!")
+# except exceptions.IncorrectClassError,e:
+# pass
+
+# def test_feature_add_child_incorrect_class(self):
+# feature = api.Feature("Feature")
+# try:
+# feature._add(api.Group("Test"))
+# self.fail("Adding incorrect class succeeds! This succeeds because of Base class support in model.")
+# except exceptions.IncorrectClassError,e:
+# pass
+
+ def test_feature_add(self):
+ feature = api.Feature("Feature")
+ feature._add(api.Feature("Test"))
+ self.assertEquals(feature._list(),['Test'])
+
+ def test_view_add_groups_and_features_and_list_all(self):
+ view = api.View("view1")
+ view._add(api.Group("group1"))
+ view._add(api.Group("group2"))
+ view._add(api._FeatureProxy("feature1"))
+ view.group1._add(api.Group("group21"))
+ view.group1.group21._add(api._FeatureProxy("feature211"))
+ view.group1.group21._add(api._FeatureProxy("feature212"))
+ view.feature1._add(api._FeatureProxy("feature11"))
+ self.assertEquals(sorted(view._list_traverse()),
+ sorted(['group1',
+ 'group2',
+ 'feature1',
+ 'group1.group21',
+ 'group1.group21.feature211',
+ 'group1.group21.feature212',
+ 'feature1.feature11']))
+
+ def test_view_add_groups_and_features_and_list_features(self):
+ view = api.View("view1")
+ view._add(api.Group("group1"))
+ view._add(api.Group("group2"))
+ view._add(api._FeatureProxy("feature1"))
+ view.group1._add(api.Group("group21"))
+ view.group1.group21._add(api._FeatureProxy("feature211"))
+ view.group1.group21._add(api._FeatureProxy("feature212"))
+ view.feature1._add(api._FeatureProxy("feature11"))
+ self.assertEquals(sorted(view.list_all_features()),
+ sorted(['feature1',
+ 'group1.group21.feature211',
+ 'group1.group21.feature212',
+ 'feature1.feature11']))
+
+
+ def test_view_add_features_with_view_add_feature(self):
+ view = api.View("view1")
+ view.add_feature(api.Feature("feature1"))
+ view.add_feature(api.Feature("feature2"), "com.nokia.s60")
+ view.com.nokia.s60.feature2.add_feature(api.Feature("feature21"))
+ self.assertEquals(sorted(view.list_all_features()),
+ sorted(['feature1',
+ 'com.nokia.s60.feature2',
+ 'com.nokia.s60.feature2.feature21',
+ ]))
+
+
+ def test_view_add_features_and_get_features(self):
+ view = api.View("view1")
+ view.add_feature(api.Feature("feature1"))
+ view.add_feature(api.Feature("feature2"), "com.nokia.s60")
+ view.com.nokia.s60.feature2.add_feature(api.Feature("feature21"))
+ self.assertEquals(view.get_feature("com.nokia.s60.feature2"), view.com.nokia.s60.feature2)
+
+ def test_view_get_features(self):
+ view = api.View("view1")
+ view.add_feature(api.Feature("feature1",type='boolean'))
+ view.add_feature(api.Feature("feature2"))
+ view.add_feature(api.Feature("feature11", type='boolean'),"feature1")
+ view.add_feature(api.Feature("feature12"),"feature1")
+ self.assertEquals(view.get_features("feature2"), [view.feature2])
+ self.assertEquals(view.get_features("feature2.*"), [])
+ self.assertEquals(view.get_features("feature1.*"), [view.feature1.feature11, view.feature1.feature12])
+ self.assertEquals(view.get_features("feature1.*", name='feature11'), [view.feature1.feature11])
+ self.assertEquals(view.get_features("**", filters=[lambda x: x.get_type()=='boolean']),
+ [view.feature1,
+ view.feature1.feature11])
+
+ def test_view_add_features_and_remove_features(self):
+ view = api.View("view1")
+ view.add_feature(api.Feature("feature1"))
+ view.add_feature(api.Feature("feature2"), "com.nokia.s60")
+ view.com.nokia.s60.feature2.add_feature(api.Feature("feature21"))
+
+ self.assertEquals(view.list_all_features(),['feature1', 'com.nokia.s60.feature2', 'com.nokia.s60.feature2.feature21'])
+ self.assertEquals(view.get_group("com.nokia.s60").list_features(),['feature2'])
+ for fearef in view.list_features():
+ view.remove_feature(fearef)
+ self.assertEquals(view.list_all_features(),['com.nokia.s60.feature2', 'com.nokia.s60.feature2.feature21'])
+
+ def test_view_add_groups_remove_groups(self):
+ view = api.View("view1")
+ view.add_group("Group one")
+ view.add_group("Group two")
+ view.add_feature(api.Feature("feature2"),"Group one")
+ self.assertEquals(view.list_groups(),['Group one', 'Group two'])
+ view.remove_group("Group two")
+ self.assertEquals(view.list_groups(),['Group one'])
+ view.get_group('Group one').add_feature(api.Feature("testing"))
+ self.assertEquals(view.get_group('Group one').list_features(),['feature2','testing'])
+ self.assertEquals(view.list_all_features(),['Group one.feature2', 'Group one.testing'])
+ view.remove_group("Group one")
+ self.assertEquals(view.list_groups(),[])
+ self.assertEquals(view.list_features(),[])
+
+ def test_view_add_featurelink(self):
+ view = api.View("view1")
+ view.add_group("Group one")
+ view.add_group("Group two")
+ view.add_feature(api.Feature("feature2"),"Group one")
+ self.assertEquals(view.list_groups(),['Group one', 'Group two'])
+ view.remove_group("Group two")
+ #view.add(api.FeatureGroup('foo.*'))
+ self.assertEquals(view.list_groups(),['Group one'])
+ view.get_group('Group one').add(api.FeatureLink("testing"))
+ g1 = view.get_group('Group one')
+ self.assertEquals(g1.list_features(),['feature2'])
+ self.assertEquals(view.list_all_features(),['Group one.feature2'])
+ view.remove_group("Group one")
+
+ self.assertEquals(view.list_groups(),[])
+ self.assertEquals(view.list_features(),[])
+
+ def compareview(self,view1,view2):
+ self.assertEquals(view1.ref, view2.ref)
+ self.assertEquals(view1.container, view2.container)
+ self.assertEquals(view1.name, view2.name)
+ self.assertEquals(view1.support_data, view2.support_data)
+
+
+ def test_clone_view_with_featurelink(self):
+ view1 = api.View("view1")
+ view1.add_group("Group one")
+ view1.add_group("Group two")
+ view1.get_group('Group one').add(api.FeatureLink("testing"))
+ fea2 = api.Feature("feature2")
+ view1.add_feature(fea2,"Group one")
+ view1.add_feature(api.Feature("feature3"),"Group one")
+ self.assertEquals(view1.list_groups(),['Group one', 'Group two'])
+
+ view2 = view1._clone(recursion=True)
+ self.compareview(view1,view2)
+ self.assertEquals(view2.list_groups(),['Group one', 'Group two'])
+ self.assertEquals(view2.get_group('Group one')._list(),['testing', 'feature2', 'feature3'])
+ #self.assertEquals(view2.get_group('Group one').feature2._obj, fea2)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/unittest_xml_parsing.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_xml_parsing.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,130 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os
+import unittest
+import StringIO
+import __init__
+
+from cone.public import utils, exceptions
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class ElementTreeBackendTester(object):
+ """
+ Base tester class that contains all test cases.
+
+ The actual test case classes derive from this and set the
+ class attributes BACKEND_ID and LINE_NUMBERS.
+ """
+
+ DATA = u"""
+
+
+
+ カタカナ
+
+
+ some text
+
+ """.encode('utf-8')
+
+ # ID of the ElementTree back-end to use in the tests
+ BACKEND_ID = None
+
+ # Whether to check if line numbers in elements are correct or None
+ LINE_NUMBERS = False
+
+ def setUp(self):
+ self.orig_backend_id = utils.etree.get_backend_id()
+ utils.etree.set_backend_id(self.BACKEND_ID)
+
+ def tearDown(self):
+ utils.etree.set_backend_id(self.orig_backend_id)
+
+ def assert_lineno_equals(self, actual, expected):
+ if self.LINE_NUMBERS:
+ self.assertEquals(actual, expected)
+ else:
+ self.assertEquals(actual, None)
+
+ def test_correct_parser_set(self):
+ self.assertEquals(utils.etree.get_backend_id(), self.BACKEND_ID)
+
+ def test_fromstring_successful(self):
+ root = utils.etree.fromstring(self.DATA)
+ self.assertEquals(root.tag, '{http://www.test.com/xml/1}root')
+ children = [e for e in root]
+ self.assertEquals(len(children), 3)
+ self.assertEquals(children[0].tag, '{http://www.test.com/xml/1}elem1')
+ self.assertEquals(children[1].tag, '{http://www.test.com/xml/1}elem2')
+ self.assertEquals(children[2].tag, '{http://www.test.com/xml/1}elem3')
+ self.assertEquals(children[1].text, u'カタカナ')
+
+ self.assert_lineno_equals(utils.etree.get_lineno(root), 2)
+ self.assert_lineno_equals(utils.etree.get_lineno(children[0]), 4)
+ self.assert_lineno_equals(utils.etree.get_lineno(children[1]), 5)
+ self.assert_lineno_equals(utils.etree.get_lineno(children[2]), 6)
+
+ def test_tostring_ascii(self):
+ root = utils.etree.fromstring(self.DATA)
+ output = utils.etree.tostring(root)
+
+ def test_tostring_utf_8(self):
+ root = utils.etree.fromstring(self.DATA)
+ output = utils.etree.tostring(root, 'UTF-8')
+
+ def test_tostring_utf_16(self):
+ root = utils.etree.fromstring(self.DATA)
+ output = utils.etree.tostring(root, 'UTF-16')
+
+ def test_fromstring_failed(self):
+ data = """
+
+
+ testing
+ """
+ try:
+ etree = utils.etree.fromstring(data)
+ self.fail("XmlParseError not raised!")
+ except exceptions.XmlParseError, e:
+ self.assertEquals(e.lineno, 4)
+
+# ============================================================================
+# Actual test cases
+# ============================================================================
+
+# NOTE:
+# The test classes MUST inherit the two super-classes in the order
+# (ElementTreeBackendTester, unittest.TestCase), or otherwise setUp() and
+# tearDown() will not be overridden correctly
+
+class TestElementTreeBackend(ElementTreeBackendTester, unittest.TestCase):
+ BACKEND_ID = utils.etree.BACKEND_ELEMENT_TREE
+ LINE_NUMBERS = True
+
+class TestCElementTreeBackend(ElementTreeBackendTester, unittest.TestCase):
+ BACKEND_ID = utils.etree.BACKEND_C_ELEMENT_TREE
+ LINE_NUMBERS = False
+
+class TestLxmlBackend(ElementTreeBackendTester, unittest.TestCase):
+ BACKEND_ID = utils.etree.BACKEND_LXML
+ LINE_NUMBERS = True
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/utils-testdata/foobar/bar.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/utils-testdata/scrot.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/tests/utils-testdata/test.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/public/utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/utils.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,621 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import os
+import re
+import StringIO
+import tokenize
+import inspect
+import traceback
+import logging
+import imghdr
+from token import ENDMARKER, NAME, NUMBER, STRING
+import api
+import mimetypes
+import exceptions
+
+import _etree_wrapper
+etree = _etree_wrapper.ElementTreeWrapper()
+
+class resourceref(object):
+ """
+ Class container for set of resource reference related functions
+ """
+ @classmethod
+ def filter_resources(cls, resources, regexp):
+ """
+ Filter out all resources that do not match the given regexp
+ @return a array of resources that match the given resource
+ """
+ test = re.compile(regexp, re.IGNORECASE)
+ return [r for r in resources if test.search(r)]
+
+ @classmethod
+ def neg_filter_resources(cls, resources, regexp):
+ """
+ Filter out all resources that do match the given regexp
+ @return a array of resources that dont match the given resource
+ """
+ test = re.compile(regexp, re.IGNORECASE)
+ return [r for r in resources if not test.search(r)]
+
+ @classmethod
+ def insert_begin_slash(cls, ref):
+ if not ref.startswith('/'):
+ return '/' + ref
+ return ref
+
+ @classmethod
+ def remove_begin_slash(cls, ref):
+ if ref.startswith('/'):
+ return ref.replace('/', '', 1)
+ return ref
+
+ @classmethod
+ def remove_end(self, path, str):
+ try:
+ (ret, sep, rest) = path.partition(str)
+ return ret
+ except ValueError:
+ return path
+
+ @classmethod
+ def add_end_slash(cls, ref):
+ if not ref.endswith('/'):
+ return ref+'/'
+ return ref
+
+ @classmethod
+ def remove_end_slash(cls, ref):
+ if ref.endswith('/'):
+ return ref[:-1]
+ return ref
+
+ @classmethod
+ def norm(cls, ref):
+ """
+ Normalize the reference to common cone form.
+ 1. Always with forward slashes
+ 2. no beginning slash
+ 3. no end slash
+ @return: A normalized reference string
+ """
+
+ # Do not modify emtpy string at all
+ if not ref == '':
+ normref = os.path.normpath(ref)
+ normref = normref.replace('\\','/').replace('"','').replace('//','/')
+ else:
+ normref = ref
+ return normref
+
+ @classmethod
+ def replace_dir(cls, ref, frompart, topart):
+ """
+ Replace a part of directory beginning from ref.
+ @param ref: the resource reference
+ @param frompart: the part of directory name to be replaced
+ @param topart: the partial name which replaces the frompart
+ @return: a refenence with forward slashes
+ """
+ # Normalize all paths and replace the name with string replace
+ #
+ normref = cls.norm(ref)
+ normfrom = cls.norm(frompart)
+ normto = cls.norm(topart)
+ # Add the end slash to from and to as it should be a dir (if not empty)
+ if normto != "": normto = cls.add_end_slash(normto)
+ if normfrom != "": normfrom = cls.add_end_slash(normfrom)
+ if normref != "": normref = cls.add_end_slash(normref)
+ retref = cls.norm(normref.replace(normfrom, normto, 1))
+ if retref != "": retref = cls.remove_end_slash(retref)
+ return retref
+
+ @classmethod
+ def join_refs(cls, refs):
+ """
+ join a list of dotted references together with dots
+ 1. ignore empty refs
+ 2. no dot include begin dot
+ 3. no dot include end dot
+ @param refs: a list of references
+ @return: A normalized dotted reference
+ """
+ # Create a copy of references without any empty strings
+ import posixpath
+ paramdict = {}
+ retref = posixpath.join(*refs)
+ #retref = "/".join([ref for ref in refs if ref != ''])
+ #subs = re.sub('/+', '/', retref)
+ return retref
+
+ @classmethod
+ def split_ref(cls, ref):
+ """
+ Replace a part of directory beginning from ref.
+ @param ref: the resource reference
+ @return: a list of path elems
+ """
+ return [r for r in ref.split('/') if r]
+
+ @classmethod
+ def psplit_ref(cls, ref):
+ """
+ pop split that splits the last element of the array
+ 1. empty ref returns an empty list
+ @param ref: a resource references string (e.g. aaa/bbb/ccc.txt)
+ @return: A tuple of references (with given param ('aaa/bbb','ccc.txt')
+ """
+ refs = ref.rsplit('/', 1)
+ return ("".join(refs[0:-1]), refs[-1])
+
+ @classmethod
+ def remove_ext(cls, ref):
+ """
+ Remove file extension from ref
+ 1. remove file extension
+ @return: a reference. E.g. (foo/test.confml) => foo/test
+ """
+ filenameparts = cls.get_filename(ref).rsplit('.', 1)
+ path = cls.get_path(ref)
+ if len(filenameparts)==2 and filenameparts[0] != "":
+ return cls.join_refs([path, filenameparts[0]])
+ else:
+ return ref
+
+ @classmethod
+ def get_ext(cls, ref):
+ """
+ get file extension from ref
+ 1. get file extension
+ @return: a reference. E.g. (foo/test.confml) => confml
+ """
+ if len(ref.rsplit('.', 1)) == 2:
+ return ref.rsplit('.', 1)[1]
+ else:
+ return ""
+
+ @classmethod
+ def get_filename(cls, ref):
+ """
+ get file name part from ref
+ 1. get file extension
+ @return: a reference. E.g. (foo/test.confml) => confml
+ """
+ return ref.rsplit('/', 1)[-1]
+
+ @classmethod
+ def get_path(cls, ref):
+ """
+ get file name part from ref
+ 1. get file extension
+ @return: a reference. E.g. (foo/test.confml) => confml
+ """
+ if len(ref.rsplit('/', 1)) == 2:
+ return ref.rsplit('/', 1)[0]
+ else:
+ return ""
+
+ @classmethod
+ def to_dottedref(cls, ref):
+ """
+ Convert a resource ref to dotted ref
+ 1. remove file extension
+ 2. convert path delims to dots
+ @return: a dotted reference. E.g. (foo/test.confml) => foo_test
+ """
+ newref = cls.remove_ext(ref).replace('/', '_').replace(' ', '_')
+ return dottedref.remove_begin_dot(newref)
+
+
+ @classmethod
+ def to_objref(cls, ref):
+ """
+ Convert a resource ref to dotted ref
+ 1. remove file extension
+ 2. convert path delims to dots
+ 3. using double underscores for directory separation
+ @return: a dotted reference. E.g. (foo/test.confml) => foo_test
+ """
+ ref = ref.replace('/', '__')
+ newref = ''
+ first_token = True
+ try:
+ for toknum, tokval, spos, epos, _ in tokenize.generate_tokens(StringIO.StringIO(unicode(ref)).readline):
+ if toknum == ENDMARKER:
+ break
+ elif toknum == NAME:
+ newref += str(tokval)
+ elif toknum == NUMBER:
+ # Add a character before the number token if the first token is a number
+ if first_token:
+ newref += '_'
+ # replace a possible dot in number .123
+ newref += str(tokval.replace('.','_'))
+ elif toknum == STRING:
+ newref += str(tokval.replace('"', ''))
+ else:
+ newref += '_'
+ # After first round set the first token to false
+ first_token = False
+ except tokenize.TokenError:
+ pass
+ return newref
+
+ @classmethod
+ def to_dref(cls, ref):
+ """
+ Convert a resource ref to dotted ref
+ 1. remove file extension
+ 2. convert path delims to dots
+ @return: a dotted reference. E.g. (foo/test.confml) => foo.test
+ """
+ return dottedref.remove_begin_dot(cls.remove_ext(ref).replace('/','.'))
+
+ @classmethod
+ def to_hash(cls, ref):
+ """
+ Convert a resource ref to to hash 32 bit integer
+ @return:
+ """
+ return "%s" % hex(hash(ref))
+
+class dottedref(object):
+ """
+ Class container for set of dotted reference related functions
+ """
+ @classmethod
+ def join_refs(cls, refs):
+ """
+ join a list of dotted references together with dots
+ 1. ignore empty refs
+ 2. no dot include begin dot
+ 3. no dot include end dot
+ @param refs: a list of references
+ @return: A normalized dotted reference
+ """
+ # Create a dotted reference without any empty strings
+ return '.'.join([ref for ref in refs if ref.strip()])
+
+ @classmethod
+ def split_ref(cls, ref):
+ """
+ split a dotted references string to a list of ref elements
+ 1. empty ref returns an empty list
+ @param ref: a dotted references string (e.g. aaa.bbb.ccc)
+ @return: A list of references (with given param ['aaa','bbb','ccc']
+ """
+ # list of reference parts without any empty strings
+ return [r for r in ref.split('.') if r]
+
+ @classmethod
+ def psplit_ref(cls, ref):
+ """
+ pop split that splits the last element of the array
+ 1. empty ref returns an empty list
+ @param ref: a dotted references string (e.g. aaa.bbb.ccc)
+ @return: A tuple of references (with given param ('aaa.bbb','ccc')
+ """
+ refs = ref.rsplit('.', 1)
+ return ("".join(refs[0:-1]), refs[-1])
+
+ @classmethod
+ def remove_last(cls, ref):
+ """
+ removes the last element of the ref
+ 1. empty ref returns an empty list
+ @param ref: a dotted references string (e.g. aaa.bbb.ccc)
+ @return: A reference (with given param ('aaa.bbb')
+ """
+ return ref.rsplit('.', 1)[0]
+
+ @classmethod
+ def get_last(cls, ref):
+ """
+ returns the last element of the ref
+ 1. empty ref returns an empty string
+ @param ref: a dotted references string (e.g. aaa.bbb.ccc)
+ @return: A reference (with given param ('ccc')
+ """
+ return ref.rsplit('.', 1)[-1]
+
+ @classmethod
+ def get_name(cls, ref):
+ """
+ returns the last element of the ref
+ 1. empty ref returns an empty string
+ @param ref: a dotted references string (e.g. aaa.bbb.ccc)
+ @return: A reference (with given param ('ccc')
+ """
+ if re.match('^(.*)\[.*\]$', ref):
+ return re.match('^(.*)\[.*\]$', ref).group(1)
+ else:
+ return ref
+
+ @classmethod
+ def get_index(cls, ref):
+ """
+ returns the last element of the ref
+ 1. empty ref returns an empty string
+ @param ref: a dotted references string (e.g. aaa.bbb.ccc)
+ @return: A reference (with given param ('ccc')
+ """
+ if re.match('^.*\[(\d+)\]$', ref):
+ return int( re.match('^.*\[(\d+)\]$', ref).group(1) )
+ else:
+ return None
+
+ @classmethod
+ def remove_begin_dot(cls, ref):
+ """
+ removes all the dots from the begin of the ref
+ @param ref: a dotted references string (e.g. .aaa.bbb.ccc)
+ @return: A reference (with given param ('aaa.bbb.ccc')
+ """
+ return ref.lstrip('.')
+
+ @classmethod
+ def ref2filter(cls, ref):
+ elems = []
+ for refelem in dottedref.split_ref(ref):
+ if refelem == "**":
+ elems.append(".*")
+ else:
+ elems.append(refelem.replace("*","[^\.]*"))
+ return "\\.".join(elems)+"$"
+
+def extract_delimited_tokens(string, delimiters=('${', '}')):
+ """
+ Return a list of all tokens delimited by the given strings in the given string.
+ This function returns basically the first row of the result of
+ extract_delimited_token_tuples(), with duplicates removed.
+
+ >>> dottedref.extract_refs("test1 ${my.ref1} test2 ${ my.ref1 } ${my.ref2}")
+ ['my.ref1', 'my.ref2']
+ """
+ ref_tuples = extract_delimited_token_tuples(string, delimiters)
+ return distinct_array([ref for ref, raw_ref in ref_tuples])
+
+def extract_delimited_token_tuples(string, delimiters=('${', '}')):
+ """
+ Extract a list of (token, raw_token) tuples from the given string.
+ 'token' is the the token extracted from the string and trimmed (surrounding
+ whitespace removed), and raw_token is the unmodified match from the
+ string, which can be used for replacing.
+
+ >>> dottedref.extract_ref_tuples("test1 ${my.ref1} test2 ${ my.ref1 } ${my.ref2}")
+ [('my.ref1', '${my.ref1}'), ('my.ref1', '${ my.ref1 }'), ('my.ref2', '${my.ref2}')]
+ """
+ pattern = '%s.*?%s' % (re.escape(delimiters[0]), re.escape(delimiters[1]))
+ matches = distinct_array(re.findall(pattern, string, re.DOTALL))
+
+ result = []
+ for match in matches:
+ ref = match[len(delimiters[0]):-len(delimiters[1])].strip()
+ result.append((ref, match))
+ return result
+
+def expand_delimited_tokens(string, expander_func, delimiters=('${', '}')):
+ """
+ Expand all tokens in the given string using the given expander function.
+
+ @param string: The string to expand.
+ @param expander_func: The function used for expanding. Should take two parameters:
+ 1 - The token to expand.
+ 2 - The index of the token in the string.
+ @param delimiters: Tuple specifying the delimiters for tokens.
+ @return: The expanded string.
+ """
+ # Collect a dictionary of token-entry pairs
+ class Entry(object):
+ pass
+ tokens = {}
+ for index, (token, raw_token) in enumerate(extract_delimited_token_tuples(string, delimiters)):
+ if token not in tokens:
+ entry = Entry()
+ entry.index = index
+ entry.raw_tokens = []
+ entry.value = unicode(expander_func(token, index))
+ tokens[token] = entry
+ else:
+ entry = tokens[token]
+
+ entry.raw_tokens.append(raw_token)
+
+ # Replace all tokens with the expanded values
+ result = string
+ for entry in tokens.itervalues():
+ for raw_token in entry.raw_tokens:
+ result = result.replace(raw_token, entry.value)
+ return result
+
+def expand_refs_by_default_view(string, default_view, delimiters=('${', '}'), default_value_for_missing=''):
+ """
+ Convenience function for expanding the refs in a string using setting values.
+ @param default_value_for_missing: The default value used if a setting for
+ a reference cannot be found.
+ @return: The expanded string.
+ """
+ def expand(ref, index):
+ try:
+ return default_view.get_feature(ref).get_original_value()
+ except exceptions.NotFound:
+ logging.getLogger('cone').error("Feature '%s' not found" % ref)
+ return default_value_for_missing
+ return expand_delimited_tokens(string, expand, delimiters)
+
+def distinct_array(arr):
+ newarray = []
+ for val in arr:
+ try:
+ # test to see whether the value already is in thearray
+ newarray.index(val)
+ except ValueError:
+ newarray.append(val)
+ return newarray
+
+
+def list_files(path):
+ """
+ Get an array of files in a folder
+ """
+ retarray = []
+ # Walk through all files in the layer
+ path = os.path.abspath(path)
+ for root, dirs, files in os.walk(path):
+ for name in files:
+ entry = os.path.join(root, name)
+ entry = os.path.normpath(os.path.abspath(entry))
+ if os.path.isfile(entry):
+ retarray.append(entry)
+ return retarray
+
+def all_subclasses(classname):
+ """
+ @return: A list of all subclasses of classname
+ """
+ subclasses = classname.__subclasses__()
+ # Create copy of the subclasses list for the iteration,
+ # so that added items are not recursed again
+ for subclass in classname.__subclasses__():
+ subclasses += all_subclasses(subclass)
+ return subclasses
+
+def pathmatch(pattern, refpath):
+ """
+ Check for matching pattern for a ref path
+ """
+ filter = dottedref.ref2filter(pattern)
+ return re.match(filter, refpath) != None
+
+def filter(obj, filters):
+ for filter in filters:
+ if not filter(obj):
+ return False
+ return True
+
+def get_list(elem):
+ if not isinstance(elem, list):
+ return [elem]
+ else:
+ return elem
+
+def add_list(elem, add):
+ retlist = get_list(elem)
+ retlist.append(add)
+ return retlist
+
+def prepend_list(elem, prepend):
+ retlist = get_list(elem)
+ retlist.insert(0, prepend)
+ return retlist
+
+def is_list(elem):
+ return isinstance(elem, list)
+
+def get_class(modelinstance, classinstance):
+ """
+ Get the actual model specific implementation class for a classinstance
+ """
+ for attr in dir(modelinstance):
+ modelclass = getattr(modelinstance, attr)
+ if inspect.isclass(modelclass):
+ if issubclass(modelclass, classinstance):
+ return modelclass
+ return classinstance
+
+class DataMapRef(object):
+ """
+ Utility class for handling map attributes in data section
+ """
+ @classmethod
+ def get_feature_ref(cls, map):
+ index = map.find("@")
+ if index != -1:
+ parts = map.split("@")
+ return parts[0][:-1]
+ else:
+ return None
+
+ @classmethod
+ def get_key_value(cls, map):
+ index = map.find("@")
+ if index != -1:
+ parts = map.split("@")
+ key = parts[1][:-1]
+ keys = key.split("=")
+ value = keys[1].strip()
+ return value[1:-1]
+ else:
+ return None
+
+
+class xml(object):
+ """
+ Class container for set of XML-related helper functions.
+ """
+
+ @classmethod
+ def split_tag_namespace(cls, xml_tag):
+ """
+ Split the given XML tag into a (namespace, tag) tuple.
+
+ >>> ReaderBase._split_tag_namespace("test")
+ (None, 'test')
+ >>> ReaderBase._split_tag_namespace("{http://www.test.com/xml/1}test")
+ ('http://www.test.com/xml/1', 'test')
+ """
+ if xml_tag.startswith('{'):
+ parts = xml_tag[1:].split('}')
+ return (parts[0], parts[1])
+ else:
+ return (None, xml_tag)
+
+def log_exception(logger, msg, msg_level=logging.ERROR, traceback_level=logging.DEBUG):
+ """
+ Log an exception so that the given message and the exception's
+ traceback are logged separately with the given log levels.
+
+ The purpose is to print minimal information to the user when running
+ the CLI (default level for STDOUT logging is WARNING), but the traceback
+ should still be available in the log file (which uses the level DEBUG
+ by default).
+
+ Note that this function should be only used in an exception handler.
+ """
+ logger.log(msg_level, msg)
+ logger.log(traceback_level, traceback.format_exc())
+
+def make_content_info(resource, data):
+ """
+ Factory for ContentInfo
+ """
+ cnt_inf = None
+
+ if resource != None:
+ guessed_type = mimetypes.guess_type(resource.get_path())
+ mimetype = None
+ mimesubtype = None
+
+ if guessed_type != None:
+ mimetype, mimesubtype = guessed_type[0].split('/')
+
+ if mimetype == 'image' and mimesubtype == 'x-ms-bmp':
+ cnt_inf = api.BmpImageContentInfo(resource, data)
+ else:
+ cnt_inf = api.ContentInfo(mimetype, mimesubtype)
+ return cnt_inf
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import os,sys,unittest
+from optparse import OptionParser, OptionGroup
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(0, os.path.join(ROOT_PATH,'..'))
+#sys.path.insert(0, os.path.join(ROOT_PATH,'../testautomation'))
+
+import cone.storage.tests
+import cone.core.tests
+import cone.confml.tests
+import cone.carbon.tests
+import cone.public.tests
+#from testautomation import testcli
+
+def collect_suite():
+ suite = unittest.TestSuite()
+ suite.addTests(cone.storage.tests.collect_suite())
+ suite.addTests(cone.core.tests.collect_suite())
+ suite.addTests(cone.confml.tests.collect_suite())
+ suite.addTests(cone.carbon.tests.collect_suite())
+ suite.addTests(cone.public.tests.collect_suite())
+ return suite
+
+if __name__ == '__main__':
+ import nose
+ setuptools_incompat = ('report', 'prepareTest',
+ 'prepareTestLoader', 'prepareTestRunner',
+ 'setOutputStream')
+
+ plugins = nose.plugins.manager.RestrictedPluginManager(exclude=setuptools_incompat)
+ allfiles = nose.config.all_config_files() + ['nose_unittests.cfg']
+ conf = nose.config.Config(files=allfiles,
+ plugins=plugins)
+ conf.configure(argv=['collector'])
+ print "conf :", conf.include
+ nose.main(config=conf)
+
+#if __name__ == '__main__':
+# testcli.run(collect_suite())
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys,os
+
+__all__ = ['resources','filestorage','zipstorage','stringstorage','webstorage']
+
+storages = ['filestorage','zipstorage','stringstorage','webstorage']
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/authenticate.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/authenticate.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,153 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+
+"""
+
+
+import getpass
+import urllib, urllib2
+import urlparse
+from HTMLParser import HTMLParser
+import sys
+import os
+import logging
+import re
+
+
+class SSOHTMLParser(HTMLParser):
+ """
+ Simple html parser which understand what is needed to show the current
+ version of the SSO login page. End parsing at <\html>, which is in
+ current version of login page inside before other stuff on page.
+ Asks form inputs of types text and password from the user.
+ The data is saved in varables inside class
+ """
+ def __init__(self, *argv, **kwargs):
+ HTMLParser.__init__(self, *argv, **kwargs)
+ self.html_end = False
+ self.httpdata = {}
+ self.input_requested = False
+ self.input_entered = False
+ self.method = ''
+ self.action = ''
+ self.username = kwargs.get('username')
+ self.password = kwargs.get('password')
+
+ def handle_starttag(self, tag, attrs):
+ attrs = dict(attrs)
+ if self.html_end:
+ return
+ if tag == 'br':
+ print
+ elif tag == 'form':
+ self.action = attrs.get('action')
+ self.method = attrs.get('method')
+ elif tag == 'input':
+ inputtype = attrs.get('type', 'text')
+ if inputtype == 'hidden':
+ # Should the username be also overridable
+ self.httpdata[attrs.get('name')] = attrs.get('value')
+ if inputtype == 'password':
+ self.input_requested = True
+ data = self.password
+ if data:
+ self.input_entered = True
+ self.httpdata[attrs.get('name')] = data
+ if inputtype == 'text':
+ self.input_requested = True
+ data = raw_input()
+ if data:
+ self.input_entered = True
+ self.httpdata[attrs.get('name')] = data
+ if inputtype == 'submit':
+ self.httpdata['submit'] = attrs.get('value')
+
+ def handle_endtag(self, tag):
+ if self.html_end:
+ return
+ if tag == 'tr':
+ print
+ if tag == 'title':
+ print
+ if tag == 'html':
+ self.html_end = True
+
+ def handle_data(self, data):
+ if self.html_end:
+ return
+ if data.strip():
+ print data.strip(),
+
+class CarbonAuthHandler(urllib2.AbstractHTTPHandler):
+ handler_order = 600
+
+ def add_password(self, username, password):
+ """
+ Add username and password
+ """
+ self.username = username
+ self.password = password
+
+ def https_response(self, request, response):
+ """
+ Catches responses which are from sso login page and asks for the
+ information from the command line and posts it.
+ After posting urllib2 takes care of following redirects back to
+ original page.
+ """
+ if (re.match('login.*\.europe\.nokia\.com', request.get_host())):
+ sso_parser = SSOHTMLParser(username=self.username, password=self.password)
+ sso_parser.feed(response.read())
+ # !sso_parser.input_requested when we have posted the form and
+ # are reading the redirect back. We don't want to handle that
+ if sso_parser.input_requested:
+ if not sso_parser.input_entered:
+ # By entering empty username and password you get
+ # out of infinite invalid login loop
+ # Only bad thing that the SSO login page doesen't
+ # tell you that login failed, only shows the same text
+ # again
+ raise urllib2.URLError("No login data entered")
+ newurl = urlparse.urljoin(request.get_full_url(), sso_parser.action)
+ ssoreq = urllib2.Request(newurl,
+ urllib.urlencode(sso_parser.httpdata),
+ origin_req_host=request.get_origin_req_host(),
+ unverifiable=True,
+ )
+ return self.parent.open(ssoreq)
+ return response
+
+ def http_response(self, request, response):
+ """
+ Catches responses which are from normal carbon authenticatoin page and uses set password if found
+ or asks for the information from the command line and posts it.
+ After posting urllib2 takes care of following redirects back to
+ original page.
+ """
+ if response.code == 200 and (re.match('.*/extauth/login/?.*', request.get_full_url())):
+ loginreq = urllib2.Request(request.get_full_url(),
+ urllib.urlencode({ 'username' : self.username,
+ 'password' : self.password,
+ 'submit' : 'login'}
+ ),
+ origin_req_host=request.get_origin_req_host(),
+ unverifiable=True,
+ )
+ return self.parent.open(loginreq)
+ else:
+ return response
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/common.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/common.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import logging
+import xml.parsers.expat
+
+from cone.public import api, utils
+from cone.storage import metadata
+
+class StorageBase(api.Storage):
+ """
+ A general base class for all storage type classes
+ """
+ METADATA_FILENAME = ".metadata"
+
+ def __init__(self,path):
+ super(StorageBase, self).__init__(path)
+ self.meta = self.read_metadata()
+
+ def get_active_configuration(self):
+ """
+ Return the active configuration.
+ If the storage holds only one configuration, it will be always active
+ """
+ root_confmls = self.list_resources("/")
+ root_confmls = utils.resourceref.filter_resources(root_confmls,"\.confml")
+ if self.meta.get_root_file() == '' and len(root_confmls) == 1:
+ return root_confmls[0]
+ else:
+ return self.meta.get_root_file()
+
+
+ def set_active_configuration(self, ref):
+ self.meta.set_root_file(ref)
+
+ def read_metadata(self):
+ meta = None
+ if not self.is_resource(self.METADATA_FILENAME):
+ logging.getLogger('cone').info("No metadata found for: %s" % (self.get_path()))
+ # return empty metadata object
+ meta = metadata.Metadata()
+ else:
+ res = self.open_resource(self.METADATA_FILENAME)
+ try:
+ try:
+ meta = metadata.MetadataReader().fromstring(res.read())
+ except xml.parsers.expat.ExpatError:
+ """ in case of xml parsing error return empty metadata """
+ meta = metadata.Metadata()
+ finally:
+ res.close()
+ return meta
+
+ def write_metadata(self):
+ # Try to update the metadata, which might fail on ZipStorage
+
+ try:
+ if self.get_mode(self.mode) != api.Storage.MODE_READ:
+ # update the active configuration
+ self.set_active_configuration(self.get_active_configuration())
+ metares = self.open_resource(self.METADATA_FILENAME,"wb")
+ metadata.MetadataWriter().toresource(self.meta,metares)
+ metares.close()
+ except Exception,e:
+ logging.getLogger('cone').error("Could not save metadata. Exception %s" % e)
+ return
+
+ def close(self):
+ if self.get_current_path() == "":
+ self.write_metadata()
+ super(StorageBase, self).close()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/configurationpersistence.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/configurationpersistence.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,118 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from cone.public import persistence
+
+# list of namespaces supported. the first one in the list is always used in writing
+CONFIGURATION_NAMESPACES = ["http://www.s60.com/xml/confml/1"]
+INCLUDE_NAMESPACES = ["http://www.w3.org/2001/xinclude","http://www.w3.org/2001/XInclude"]
+
+class ConfigurationReader(persistence.ConeReader):
+ """
+ Parses a single CPF configuration project root confml file. Parses the XInclude statements to
+ find out the layers inside the project
+ """
+
+ class_type = "Configuration"
+
+ def __init__(self):
+ self.configuration_namespaces = CONFIGURATION_NAMESPACES
+ self.include_namespaces = INCLUDE_NAMESPACES
+
+ def fromstring(self, xml_as_string):
+ configuration = api.CompositeConfiguration(None)
+ etree = ElementTree.fromstring(xml_as_string)
+ configuration.desc = self.parse_desc(etree)
+ configuration.meta = self.parse_meta(etree)
+ configuration.set_name(self.parse_name(etree))
+ for inc in self.parse_includes(etree):
+ configuration.add_layer(inc)
+
+ return configuration
+
+ def parse_includes(self,etree):
+ include_elems = []
+ include_elems.extend(etree.getiterator("{%s}include" % self.include_namespaces[0]))
+ include_elems.extend(etree.getiterator("{%s}include" % self.include_namespaces[1]))
+ includes = []
+ for inc in include_elems:
+ includes.append(inc.get('href').replace('#/',''))
+ return includes
+
+ def parse_meta(self,etree):
+ meta_elem = etree.find("{%s}meta" % self.configuration_namespaces[0])
+ meta = {}
+ if meta_elem:
+ # There must be a nicer way to do this!! :(
+ for elem in meta_elem.getiterator():
+ m = re.match("{.*}(?P.*)",elem.tag)
+ if m and m.group('tagname') != 'meta':
+ meta[m.group('tagname')] = elem.text
+ return meta
+
+ def parse_desc(self,etree):
+ desc = ""
+ desc_elem = etree.find("{%s}desc" % self.configuration_namespaces[0])
+ if desc_elem != None:
+ desc = desc_elem.text
+ return desc
+
+ def parse_name(self,etree):
+ return etree.get("name")
+
+
+class ConfigurationWriter(persistence.ConeWriter):
+ """
+ Parses a single CPF configuration project root confml file. Parses the XInclude statements to
+ find out the layers inside the project
+ """
+
+ class_type = "Configuration"
+
+ def __init__(self):
+ self.configuration_namespace = CONFIGURATION_NAMESPACES[0]
+ self.include_namespace = INCLUDE_NAMESPACES[0]
+
+ def tostring(self,configuration,indent=True):
+ root = ElementTree.Element("configuration")
+ root.set("xmlns",self.configuration_namespace)
+ root.set("xmlns:xi",self.include_namespace)
+ root.set("name",configuration.ref)
+ root.append(self.to_desc(configuration.desc))
+ root.append(self.to_meta(configuration.meta))
+ for inc in configuration.list_layers():
+ root.append(self.to_include(inc))
+ if indent:
+ self.indent(root)
+ return ElementTree.tostring(root)
+
+ def to_desc(self,desc):
+ elem = ElementTree.Element("desc")
+ elem.text = desc
+ return elem
+
+ def to_meta(self,meta):
+ elem = ElementTree.Element("meta")
+ for key in meta.keys():
+ selem = ElementTree.SubElement(elem,key)
+ selem.text = meta[key]
+ return elem
+
+ def to_include(self,include):
+ elem = ElementTree.Element("xi:include")
+ elem.set("href",include)
+ return elem
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/filestorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/filestorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,350 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import re
+import logging
+import xml.parsers.expat
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImpotError:
+ from xml.etree import ElementTree
+
+from cone.public import exceptions
+from cone.public import api, utils
+#from cone.storage.configurationpersistence import ConfigurationReader, ConfigurationWriter
+from cone.storage import metadata, common
+from cone.confml import persistentconfml
+debug = 0
+
+class FileStorage(common.StorageBase):
+ """
+ A file system based implementation for Storage.
+ @param path : path to the storage folder
+ @param mode: the mode for the folder. Default is a=append that expects the folder to exist.
+ """
+
+ def __init__(self,path,mode="r", **kwargs):
+ super(FileStorage, self).__init__(path)
+ self.logger = logging.getLogger('cone')
+ self.logger.debug("FileStorage path %s" % self.get_path())
+ self.persistentmodule = persistentconfml
+ self.mode = mode
+ if mode.find("a")!=-1 or mode.find("r")!=-1:
+ # check that the given folder exists and is a folder
+ if not os.path.isdir(self.get_path()):
+ raise exceptions.StorageException("The given data folder for storage does not exist! %s" % self.get_path())
+ elif mode.find("w")!=-1:
+ # check if the given folder exists and create it if it does not
+ if not os.path.exists(os.path.abspath(self.get_path())):
+ os.makedirs(self.get_path())
+ else:
+ raise exceptions.StorageException("Unsupported creation mode given! %s" % mode)
+
+
+
+ @classmethod
+ def supported_storage(cls,path):
+ """
+ Class method for determing if the given clas supports a storage by given path.
+ E.g. foo.zip, foo.cpd, foo/bar, http://foo.com/
+ @param path:
+ @return: Boolean value. True if the storage of the path is supported. False if not.
+ """
+ if path.startswith('http://'):
+ return False
+ path = os.path.abspath(path)
+ (name,ext) = os.path.splitext(path)
+ if path != "" and ext == "":
+ return True
+ elif os.path.isdir(path):
+ return True
+ else:
+ return False
+
+ def open_resource(self,path,mode="r"):
+ # make sure that path exists if we are creating a file
+ path = utils.resourceref.remove_end_slash(path)
+ path = utils.resourceref.remove_begin_slash(path)
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ fullpath = utils.resourceref.join_refs([self.get_path(),path])
+ if mode.find("w") != -1:
+ dirpath = os.path.dirname(fullpath)
+ if not os.path.exists(dirpath):
+ os.makedirs(dirpath)
+ try:
+ res = FileResource(self,path,mode,open(fullpath,mode))
+ self.__opened__(res)
+ return res
+ except IOError,e:
+ raise exceptions.NotResource("%s, %s" % (path,e) )
+
+ def delete_resource(self,path):
+ if self.is_resource(path):
+ try:
+ path = utils.resourceref.remove_begin_slash(path)
+ path = utils.resourceref.join_refs([self.get_path(),self.get_current_path(),path])
+ for res in self.__get_open__(path):
+ res.close()
+ self.__closed__(res)
+ os.unlink(path)
+ except IOError:
+ raise exceptions.NotResource(path)
+ else:
+ raise exceptions.NotResource(path)
+
+ def close_resource(self, res):
+ """
+ Close the given resource instance. Normally this is called by the Resource object
+ in its own close.
+ @param res: the resource object to close.
+ """
+ try:
+ self.__closed__(res)
+ #if not res.get_mode() == api.Storage.MODE_READ:
+ # self._get(utils.resourceref.to_dref(res.path)).data = res.getvalue()
+ except KeyError,e:
+ raise exceptions.StorageException("No such %s open resource! %s" % (res.path,e))
+
+
+ def save_resource(self, res):
+ """
+ Flush the changes of a given resource instance. Normally this is called by the Resource object
+ in its own save.
+ @param res: the resource to the resource to save.
+ """
+ if not self.__has_resource__(res):
+ raise exceptions.NotResource("No such %s open resource!" % res.path)
+ else:
+ res.save()
+
+ def is_resource(self,path):
+ path = utils.resourceref.remove_begin_slash(path)
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ path = utils.resourceref.join_refs([self.get_path(),path])
+ norm_path = os.path.normpath(path)
+ return os.path.isfile(norm_path)
+
+ def fix_entry(self,entry,current_root):
+ entry = entry.replace(current_root,'')
+ entry = entry.replace("\\","/")
+ entry = utils.resourceref.remove_begin_slash(entry)
+ return entry
+
+
+ def list_resources(self,path,recurse=False,empty_folders=False):
+ """
+ Get an array of files in a folder
+ """
+
+ retarray = []
+ path = utils.resourceref.remove_begin_slash(path)
+ fullpath = utils.resourceref.join_refs([self.get_path(),self.get_current_path(),path])
+ joined = os.path.join(self.get_path(), self.get_current_path())
+ current_root = os.path.normpath(os.path.abspath(joined))
+ # return always unix type file paths
+ if recurse:
+ # Walk through all files in the layer
+ for root, dirs, files in os.walk(fullpath):
+ for name in files:
+ entry = os.path.join(root, name)
+ entry = os.path.normpath(os.path.abspath(entry))
+ if os.path.isfile(entry):
+ retarray.append(self.fix_entry(entry,current_root))
+
+ if empty_folders:
+ for name in dirs:
+ entry = os.path.join(root, name)
+ entry = os.path.normpath(os.path.abspath(entry))
+ if os.path.isdir(entry) and len(os.listdir(entry)) ==0:
+ retarray.append(self.fix_entry(entry,current_root))
+
+ else:
+ filelist = os.listdir(fullpath)
+ for name in filelist:
+ entry = os.path.join(path, name)
+ entry = os.path.normpath(entry)
+ entry = entry.replace("\\","/")
+ entry = utils.resourceref.remove_begin_slash(entry)
+ # ignore non file entries
+ fileentry = os.path.join(current_root,entry)
+ if os.path.isfile(fileentry):
+ if debug: print "list_resources adding %s" % entry
+ retarray.append(entry)
+
+ if os.path.isdir(fileentry) and empty_folders:
+ if debug: print "list_resources adding %s" % entry
+ retarray.append(entry)
+ return retarray
+
+ def import_resources(self,paths,storage):
+ for path in paths:
+ if not storage.is_resource(path):
+ logging.getLogger('cone').warning("The given path is not a Resource in the storage %s! Ignoring from export!" % path)
+ continue
+ wres = self.open_resource(path,'wb')
+ res = storage.open_resource(path,"rb")
+ wres.write(res.read())
+ wres.close()
+ res.close()
+
+ def export_resources(self,paths,storage,empty_folders=False):
+ """
+
+
+ """
+ for path in paths:
+ if not self.is_resource(path) and empty_folders==False:
+ logging.getLogger('cone').warning("The given path is not a Resource in this storage %s! Ignoring from export!" % path)
+ continue
+ if self.is_resource(path):
+ wres = storage.open_resource(path,'wb')
+ res = self.open_resource(path,"rb")
+ wres.write(res.read())
+ wres.close()
+ res.close()
+
+
+ if self.is_folder(path) and empty_folders:
+ storage.create_folder(path)
+
+
+
+
+ def create_folder(self,path):
+ """
+ Create a folder entry to a path
+ @param path : path to the folder
+ """
+
+ path = utils.resourceref.join_refs([self.get_path(), self.get_current_path(), path])
+ if not os.path.exists(path):
+ os.makedirs(path)
+
+ def delete_folder(self,path):
+ """
+ Delete a folder entry from a path. The path must be empty.
+ @param path : path to the folder
+ """
+ path = utils.resourceref.join_refs([self.get_path(), self.get_current_path(), path])
+ if os.path.isdir(path):
+ os.rmdir(path)
+ else:
+ raise exceptions.StorageException("Not a folder %s" % path)
+
+ def is_folder(self,path):
+ """
+ Check if the given path is an existing folder in the storage
+ @param path : path to the folder
+ """
+ path = utils.resourceref.join_refs([self.get_path(), self.get_current_path(), path])
+ return os.path.isdir(path)
+
+ def unload(self, path, object):
+ """
+ Dump a given object to the storage (reference is fetched from the object)
+ @param object: The object to dump to the storage, which is expected to be an instance
+ of Base class.
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ if not isinstance(object, api.Configuration):
+ raise exceptions.StorageException("Cannot dump object type %s" % object.__class__)
+ # Skip the unload storing to storage if the storage is opened in read mode
+ if self.get_mode(self.mode) != api.Storage.MODE_READ:
+ res = self.open_resource(path,"wb")
+ data = self.persistentmodule.dumps(object)
+ res.write(data)
+ res.close()
+ return
+
+
+ def load(self, path):
+ """
+ Load an from a reference.
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ if not utils.resourceref.get_ext(path) == "confml":
+ raise exceptions.StorageException("Cannot load reference type %s" % utils.resourceref.get_ext(path))
+ if self.is_resource(path):
+ res = self.open_resource(path,"r")
+ # read the resource with persistentmodule
+ try:
+ obj = self.persistentmodule.loads(res.read())
+ #obj.set_path(path)
+ res.close()
+ return obj
+ except exceptions.ParseError,e:
+ logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
+ # returning an empty config in case of xml parsing failure.
+ return api.Configuration(path)
+ else:
+ raise exceptions.NotResource("No such %s resource!" % path)
+
+
+class FileResource(api.Resource):
+ def __init__(self,storage,path,mode,handle):
+ api.Resource.__init__(self,storage,path,mode)
+ self.handle = handle
+
+ def read(self,bytes=0):
+ if bytes == 0:
+ return self.handle.read()
+ else:
+ return self.handle.read(bytes)
+
+ def write(self,string):
+ if self.get_mode() == api.Storage.MODE_READ:
+ raise exceptions.StorageException("Writing attempted to %s in read-only mode." % self.path)
+ else:
+ self.handle.write(string)
+
+ def truncate(self, size=0):
+ self.handle.truncate(0)
+ self.handle.seek(size, 0)
+
+ def save(self):
+ if not self.handle.closed:
+ self.handle.save()
+
+ def close(self):
+ self.storage.close_resource(self)
+ self.handle.close()
+
+ def get_size(self):
+ if self.get_mode() == api.Storage.MODE_WRITE:
+ raise exceptions.StorageException("Reading size attempted to %s in write-only mode." % self.path)
+ orig_pos = self.handle.tell()
+ self.handle.seek(0, os.SEEK_END)
+ try: return self.handle.tell()
+ finally: self.handle.seek(orig_pos, os.SEEK_SET)
+
+ def get_content_info(self):
+ orig_pos = self.handle.tell()
+ self.handle.seek(0, os.SEEK_SET)
+ data = self.handle.read()
+ self.handle.seek(orig_pos, os.SEEK_SET)
+ if self.content_info == None:
+ self.content_info = utils.make_content_info(self, data)
+
+ return self.content_info
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/metadata.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/metadata.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,111 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+import StringIO
+import os
+
+from cone.public import exceptions, persistence
+
+class Metadata(object):
+ """
+ metadata container objectl, which is only a dictionary container
+ """
+ META_ROOT_FILE = 'cpf.rootFile'
+
+ def __init__(self, copyobj=None):
+ """
+ Constructor initializes the default values
+ """
+ self.data = {}
+ if copyobj != None:
+ self.data = copyobj.data.copy()
+ pass
+
+ def get_root_file(self):
+ return self.data.get(self.META_ROOT_FILE,"")
+
+ def set_root_file(self,filename):
+ self.data[self.META_ROOT_FILE] = filename
+
+class MetadataReader(persistence.ConeReader):
+ """
+ Parses a single metadata file
+ """
+ class_type = "Metadata"
+ NAMESPACES = ['http://www.nokia.com/xml/ns/confml-core/metadata-2.0']
+ def __init__(self):
+ return
+
+ def fromstring(self, xml_as_string):
+ meta = Metadata()
+ etree = ElementTree.fromstring(xml_as_string)
+ iter = etree.getiterator("{%s}property" % self.NAMESPACES[0])
+ for elem in iter:
+ (key,value) = self.get_property(elem)
+ meta.data[key] = value
+ return meta
+
+ def get_property(self, elem):
+ key = elem.get('name')
+ value = ''
+ if elem.get('value'): value = elem.get('value')
+ return (key,value)
+
+class MetadataWriter(persistence.ConeWriter):
+ """
+ Writes a single metadata file
+ """
+ class_type = "Metadata"
+ NAMESPACES = ['http://www.nokia.com/xml/ns/confml-core/metadata-2.0']
+ DEFAULT_ENCODING = "ASCII"
+ def __init__(self):
+ self.encoding = self.DEFAULT_ENCODING
+ return
+
+ def tostring(self,obj,indent=True):
+ stringdata = StringIO.StringIO()
+ self.toresource(obj, stringdata, indent)
+ return stringdata.getvalue()
+
+ def toresource(self,obj,res,indent=True):
+ root = ElementTree.Element("metadata")
+ root.set('xmlns',self.NAMESPACES[0])
+ if not obj.__class__ == Metadata:
+ raise exceptions.IncorrectClassError('The given object is not a instance of %s' % Metadata)
+ for key in obj.data.keys():
+ prop = ElementTree.SubElement(root,'property')
+ self.set_property(prop, key, obj.data[key])
+ if indent:
+ persistence.indent(root)
+ # some smarter way to implement adding of the encoding to the beginning of file
+ res.write('%s' % (self.encoding,os.linesep))
+ ElementTree.ElementTree(root).write(res)
+
+ def set_property(self, elem, key, value):
+ elem.attrib['name'] = key
+ if value != '':
+ elem.attrib['value'] = value
+ return elem
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/persistentdictionary.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/persistentdictionary.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,222 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from cone.public import persistence, exceptions, api, utils
+
+def dumps(obj):
+ return DictWriter().dumps(obj)
+
+def loads(dictstr):
+ # convert the dict string with eval to actual dict
+ return DictReader().loads(eval(dictstr))
+
+class DictWriter(persistence.ConeWriter):
+ """
+ """
+
+ def dumps(self, obj):
+ """
+ @param obj: The object
+ """
+ writer = get_writer_for_class(obj.__class__.__name__)
+ return {obj.__class__.__name__: writer.dumps(obj)}
+
+
+class DictReader(persistence.ConeReader):
+ """
+ """
+ class_type = "Dict"
+
+ def loads(self, dict):
+ """
+ @param dict: The dictianary which to read. reads only the first object.
+ """
+ classname = dict.keys()[0]
+ reader = get_reader_for_elem(classname)
+ return reader.loads(dict)
+
+
+class GenericWriter(DictWriter):
+ """
+ """
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ dict = {'dict': todict(obj)}
+ for child in obj._objects():
+ writer = get_writer_for_class(child.__class__.__name__)
+ chd = writer.dumps(child)
+ if not dict.has_key('children'):
+ dict['children'] = []
+ dict['children'].append({child.__class__.__name__: chd})
+ return dict
+
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this DictWriter supports writing
+ of the given class name
+ """
+ try:
+ cls = get_class(classname)
+ return True
+ except exceptions.IncorrectClassError:
+ return False
+
+
+class GenericReader(DictReader):
+ """
+ """
+
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this DictWriter supports reading
+ of the given elem name
+ """
+ try:
+ cls = get_class(elemname)
+ return True
+ except exceptions.IncorrectClassError:
+ return False
+
+ def __init__(self):
+ pass
+
+ def loads(self, dict):
+ """
+ @param obj: The Configuration object
+ """
+
+ (classname,objdata) = dict.popitem()
+ obj = get_class(classname)()
+ objdict = objdata.get('dict',{})
+ for membername in objdict.keys():
+ try:
+ setattr(obj, membername, objdict[membername])
+ except AttributeError:
+ # read only attributes cannot be set
+ pass
+ obj._name = utils.resourceref.to_objref(obj.ref)
+
+ #container.ObjectContainer.__init__(obj,utils.resourceref.to_dottedref(obj.ref))
+ for child in objdata.get('children',[]):
+ classname = child.keys()[0]
+ reader = get_reader_for_elem(classname)
+ childobj = reader.loads(child)
+ obj.add(childobj)
+ return obj
+
+
+class ConfigurationProxyWriter(DictWriter):
+ """
+ """
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+ dict = {'dict': todict(obj)}
+ return dict
+
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this DictWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfigurationProxy":
+ return True
+ else:
+ return False
+
+
+class ConfigurationProxyReader(DictReader):
+ """
+ """
+ def loads(self, dict):
+ """
+ @param obj: The Configuration object
+ """
+ (classname,objdata) = dict.popitem()
+ obj = api.ConfigurationProxy("")
+ obj.__dict__.update(objdata.get('dict',{}))
+ obj.set('_name',utils.resourceref.to_objref(obj.path))
+ return obj
+
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this DictWriter supports reading
+ of the given elem name
+ """
+ if elemname=="ConfigurationProxy":
+ return True
+ else:
+ return False
+
+
+def get_class(elemname):
+ """
+ Get a correct class from a element name.
+ """
+ if elemname=="Configuration":
+ return api.Configuration
+ elif elemname=="CompositeConfiguration":
+ return api.CompositeConfiguration
+ elif elemname=="Feature":
+ return api.Feature
+ elif elemname=="Data":
+ return api.Data
+ elif elemname=="DataContainer":
+ return api.DataContainer
+ elif elemname=="Base":
+ return api.Base
+ else:
+ raise exceptions.IncorrectClassError("Could not find a class for name %s!" % elemname)
+
+def get_reader_for_elem(classname):
+ for reader in DictReader.__subclasses__():
+ if reader.supported_elem(classname):
+ return reader()
+ raise exceptions.ConePersistenceError("No reader for given class found!")
+
+def get_writer_for_class(classname):
+ for writer in DictWriter.__subclasses__():
+ if writer.supported_class(classname):
+ return writer ()
+ raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname)
+
+def todict(obj):
+ """
+ Helper function to push all non internal data to a dictionary
+ """
+ dict = {}
+ fromdict = obj._dict()
+ for member in fromdict:
+ if member.startswith("_"):
+ # skip internals
+ continue
+ value = getattr(obj,member)
+ if isinstance(value,str):
+ dict[member] = value
+ continue
+ if isinstance(value,int):
+ dict[member] = value
+ continue
+ return dict
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/resources.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/resources.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,82 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import zipfile,os,re,zlib
+from cone.public.api import Resource
+
+class CpfRootResource(Resource):
+ """
+ Parses a single CPF configuration project root confml file. Parses the XInclude statements to
+ find out the layers inside the project
+ """
+ def __init__(self):
+ self.configuration_namespace = "http://www.s60.com/xml/confml/1"
+ self.include_namespace = "http://www.w3.org/2001/xinclude"
+ self.desc = ""
+ self.includes = []
+ self.meta = {}
+ self.filename = "defaultroot.confml"
+ return
+
+ def parse_file(self, xmlfile):
+ self.filename = xmlfile
+ self.etree = ElementTree.parse(xmlfile)
+ self.parse_includes()
+ self.parse_meta()
+ self.parse_desc()
+ return
+
+ def parse_str(self, xml_as_string):
+ self.etree = ElementTree.fromstring(xml_as_string)
+ self.parse_includes()
+ self.parse_meta()
+ self.parse_desc()
+ return
+
+ def parse_includes(self):
+ includes = self.etree.getiterator("{%s}include" % self.include_namespace)
+ for inc in includes:
+ self.includes.append(inc.get('href'))
+
+ def parse_meta(self):
+ meta = self.etree.find("{%s}meta" % self.configuration_namespace)
+ if meta:
+ for elem in meta.getiterator():
+ m = re.match("{.*}(?P.*)",elem.tag)
+ if m:
+ self.meta[m.group('tagname')] = elem.text
+
+ def parse_desc(self):
+ desc_elem = self.etree.find("{%s}desc" % self.configuration_namespace)
+ if desc_elem != None:
+ self.desc = desc_elem.text
+
+ def get_layers(self):
+ return self.includes
+
+ def get_meta(self):
+ return self.meta
+
+ def get_desc(self):
+ return self.desc
+
+ def get_configuration(self):
+ configuration = CpfConfiguration(self.filename)
+ for inc in self.includes:
+ configuration.add_layer(CpfLayer(inc))
+ return configuration
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/stringstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/stringstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,353 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import StringIO
+import os
+import pickle
+import copy
+import logging
+
+from cone.public import *
+from cone.storage import persistentdictionary
+
+
+class _StringStorageObject(container.ObjectContainer):
+ def __init__(self, name):
+ container.ObjectContainer.__init__(self, utils.resourceref.to_dottedref(name))
+ self.path = name
+ self.data = ""
+
+ def get_path(self):
+ """
+ Return the path of the configuration resource
+ """
+ return self.path
+
+ def set_path(self,path):
+ """
+ Set the path of the configuration resource
+ """
+ self.path = path
+
+ def path_to_elem(self, toparent=None):
+ parent_path = ""
+ # check if the parent is found at all from this hierarchy
+ if toparent and not self._find_parent_or_default(match=toparent):
+ toparent = self._find_parent_or_default(container=True)
+ if self._find_parent():
+ parent_path = self._find_parent()._path(toparent).replace(".","/")
+ return utils.resourceref.join_refs([parent_path,self.get_path()])
+
+ def __getstate__(self):
+ return self.__dict__.copy()
+
+ def __setstate__(self,dict):
+ self.__dict__ = dict.copy()
+
+class StringStorage(api.Storage, container.ObjectContainer):
+ """
+ A general base class for all storage type classes
+ @param path : the reference to the root of the storage.
+ """
+ def __init__(self, path):
+ container.ObjectContainer.__init__(self,"")
+ api.Storage.__init__(self,path)
+
+ def __getstate__(self):
+ dict = self.__dict__.copy()
+ del dict['__opened_res__']
+ return dict
+
+ def __setstate__(self,dict):
+ self.__dict__ = dict.copy()
+ self.__dict__['__opened_res__'] = {}
+
+ def __dump__(self):
+ """
+ Dump the storage to the reference file
+ """
+ file = open(self.get_path(),"w")
+ pickle.dump(self,file)
+ file.close()
+
+ @classmethod
+ def __open__(cls,path, mode="r"):
+ if mode.find("a")!=-1 or mode.find("r")!=-1:
+ if os.path.exists(path) and os.path.isfile(path):
+ file = open(path,"r")
+ obj = pickle.load(file)
+ file.close()
+ else:
+ raise exceptions.StorageException("The given data file for storage does not exist! %s" % path)
+ elif mode.find("w")!=-1:
+ # check if the given storage path exists and delete it if it does
+ if os.path.dirname(path) != '' and not os.path.exists(os.path.dirname(path)):
+ os.makedirs(os.path.dirname(path))
+ obj = StringStorage(path)
+ """ key value pairs of data. Key path = datastring """
+ else:
+ raise exceptions.StorageException("Unsupported creation mode given! %s" % mode)
+ return obj
+
+ @classmethod
+ def supported_storage(cls,path):
+ """
+ Class method for determing if the given clas supports a storage by given path.
+ E.g. foo.zip, foo.cpd, foo/bar, http://foo.com/
+ @param path:
+ @return: Boolean value. True if the storage of the path is supported. False if not.
+ """
+ if utils.resourceref.get_ext(path) == "pk":
+ return True
+ else:
+ return False
+
+ def close(self):
+ """
+ Close the repository, which will save and close all open resources.
+ """
+ super(StringStorage,self).close()
+ self.__dump__()
+
+ def save(self):
+ """
+ Save changes from all resources to the repository.
+ """
+ super(StringStorage,self).save()
+ self.__dump__()
+
+ def open_resource(self,path,mode="r"):
+ """
+ Open the given resource and return a File object.
+ @param path : reference to the resource
+ @param mode : the mode in which to open. Can be one of r = read, w = write, a = append.
+ raises a NotResource exception if the path item is not a resource.
+ """
+ res = None
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ dottedref = utils.resourceref.to_dref(path)
+ (pathto,name)= utils.resourceref.psplit_ref(path)
+ (dpath, dref) = utils.dottedref.psplit_ref(dottedref)
+
+ # check for existence
+ if self.get_mode(mode) == self.MODE_READ:
+ try:
+ # Try to create a new StringResource in any case
+
+ res = StringResource(self, path, self._get(dottedref).data,mode)
+ except exceptions.NotFound,e:
+ raise exceptions.NotResource("Not found %s" % path)
+ elif self.get_mode(mode) == self.MODE_WRITE:
+ # Create a new StringResource in any case
+ self._add_to_path(dpath,_StringStorageObject(name))
+ res = StringResource(self, path, self._get(dottedref).data,mode)
+ elif self.get_mode(mode) == self.MODE_APPEND:
+ # Append case, create the data reference if it is not existing
+ if not self._has(dottedref):
+ self._add_to_path(dpath,_StringStorageObject(name))
+ # Create a new StringResource in any case
+ res = StringResource(self, path, self._get(dottedref).data,mode)
+ res.seek(0, os.SEEK_END)
+ self.__opened__(res)
+ return res
+
+ def delete_resource(self,path):
+ """
+ Delete the given resource from storage
+ @param res : Resource objcet to the resource
+ raises a NotSupportedException exception if delete operation is not supported by the storage
+ """
+ # First close all open resources
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.curpath, path])
+ for res in self.__get_open__(path):
+ self.__closed__(res)
+ self._remove(utils.resourceref.to_dref(path))
+
+ def close_resource(self, res):
+ """
+ Close the given resource instance. Normally this is called by the Resource object
+ in its own close.
+ @param res: the resource object to close.
+ """
+ try:
+ self.__closed__(res)
+ if not res.get_mode() == api.Storage.MODE_READ:
+ self._get(utils.resourceref.to_dref(res.path)).data = res.getvalue()
+ except KeyError,e:
+ raise StorageException("No such %s open resource! %s" % (res.path,e))
+
+
+ def save_resource(self, res):
+ """
+ Flush the changes of a given resource instance. Normally this is called by the Resource object
+ in its own save.
+ @param res: the resource to the resource to save.
+ """
+ if not self.__has_resource__(res):
+ raise exceptions.NotResource("No such %s open resource!" % res.path)
+ else:
+ if not res.get_mode() == api.Storage.MODE_READ:
+ self._get(utils.resourceref.to_dref(res.path)).data = res.getvalue()
+
+ def is_resource(self,path):
+ """
+ Return true if the path is a resource
+ @param path : reference to path where resources are searched
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ return self._has(utils.resourceref.to_dref(path))
+
+ def list_resources(self,path,recurse=False,empty_folders=False):
+ """
+ find the resources under certain path/path
+ @param path : reference to path where resources are searched
+ @param recurse : defines whether to return resources directly under the path or does the listing recurse to subfolders.
+ Default value is False. Set to True to enable recursion.
+ """
+ """ Get the given curpath element """
+ try:
+ curelem = self._get(utils.resourceref.to_dref(self.get_current_path()))
+ dref = utils.resourceref.to_dref(path)
+ if recurse:
+ return sorted([child.path_to_elem(curelem) for child in curelem._get(dref)._traverse(type=_StringStorageObject)])
+ else:
+ return sorted([child.path_to_elem(curelem) for child in curelem._get(dref)._objects(type=_StringStorageObject)])
+ except exceptions.NotFound:
+ return []
+
+ def import_resources(self,paths,storage,empty_folders=False):
+ for path in paths:
+ if not storage.is_resource(path):
+ logging.getLogger('cone').warning("The given path is not a Resource in the storage %s! Ignoring from export!" % path)
+ continue
+ wres = self.open_resource(path,'wb')
+ res = storage.open_resource(path,"rb")
+ wres.write(res.read())
+ wres.close()
+ res.close()
+
+
+ def create_folder(self,path):
+ """
+ Create a folder entry to a path
+ @param path : path to the folder
+ """
+ if not self._has(utils.resourceref.to_dref(path)):
+ (dpath,name) = utils.dottedref.psplit_ref(utils.resourceref.to_dref(path))
+ self._add_to_path(dpath, self._default_object(name))
+
+ def delete_folder(self,path):
+ """
+ Delete a folder entry from a path. The path must be empty.
+ @param path : path to the folder
+ """
+ self._remove(utils.resourceref.to_dref(path))
+
+ def is_folder(self,path):
+ """
+ Check if the given path is an existing folder in the storage
+ @param path : path to the folder
+ """
+ return self._has(utils.resourceref.to_dref(path))
+
+ def export_resources(self,refs,storage,empty_folders=False):
+ """
+ export resources from this storage based on a list of reference to this storage
+ @param refs : a list of resource names in this storage (references).
+ @param storage : the external storage where to export.
+ """
+ storage.import_resources(refs, self, empty_folders=empty_folders)
+
+ def unload(self, path, object):
+ """
+ Dump a given object to the storage (reference is fetched from the object)
+ @param object: The object to dump to the storage, which is expected to be an instance
+ of Base class.
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ if not isinstance(object, api.Configuration):
+ raise exceptions.StorageException("Cannot dump object type %s" % object.__class__)
+ res = self.open_resource(path,"w")
+ data = persistentdictionary.dumps(object)
+ res.write(data)
+ res.close()
+ return
+
+ def load(self, path):
+ """
+ Load an from a reference.
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ if not utils.resourceref.get_ext(path) == "confml":
+ raise exceptions.StorageException("Cannot load object from given path = %s!" % path)
+ if self.is_resource(path):
+ res = self.open_resource(path,"r")
+ # read the dictionary from the resource with eval
+ obj = persistentdictionary.loads(res.read())
+ res.close()
+ return obj
+ else:
+ raise exceptions.NotResource("No such %s resource!" % path)
+
+class StringResource(api.Resource):
+ """
+ A StringResource class that works on top of StringIO buffer. This class in
+ intended mainly for testing purposes.
+ """
+ def __init__(self,storage,path,stringdata, mode=api.Storage.MODE_READ):
+ strio = StringIO.StringIO(stringdata)
+ api.Resource.__init__(self,storage,path, mode)
+ self.handle = strio
+ self.read = self.handle.read
+ self.tell = self.handle.tell
+ self.seek = self.handle.seek
+ self.readline = self.handle.readline
+ self.getvalue = self.handle.getvalue
+
+ def write(self, string):
+ if self.get_mode() == api.Storage.MODE_READ:
+ raise exceptions.StorageException("Writing attempted to %s in read-only mode." % self.path)
+ else:
+ self.handle.write(string)
+
+ def read(self, bytes=0):
+ if self.get_mode() == api.Storage.MODE_WRITE:
+ raise exceptions.StorageException("Reading attempted to %s in write-only mode." % self.path)
+ else:
+ self.handle.read(string)
+
+ def save(self):
+ self.storage.save_resource(self)
+
+ def close(self):
+ self.storage.close_resource(self)
+ self.handle.close()
+
+ def get_size(self):
+ if self.get_mode() == api.Storage.MODE_WRITE:
+ raise exceptions.StorageException("Reading resource size attempted to %s in write-only mode." % self.path)
+ return len(self.handle.getvalue())
+
+ def get_content_info(self):
+ if self.content_info == None:
+ self.content_info = utils.make_content_info(self, self.handle.getvalue())
+
+ return self.content_info
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+TESTAUTO_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../testautomation'))
+if SOURCE_ROOT not in sys.path:
+ sys.path.insert(0,SOURCE_ROOT)
+if TESTAUTO_ROOT not in sys.path:
+ sys.path.insert(0,TESTAUTO_ROOT)
+
+# Find all unittest_*.py files in this folder
+import re
+__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
+# Strip .py endings
+__all__ = map(lambda name: name[:-3], __all__)
+
+def collect_suite():
+ sys.path.insert(0, ROOT_PATH)
+ try:
+ suite = unittest.TestSuite()
+ for test_module in __all__:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+ finally:
+ del sys.path[0]
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data.zip
Binary file configurationengine/source/cone/storage/tests/data.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/data/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/familyX/confml/data.confml
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/familyX/content/test/override.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/data/familyX/content/test/override.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+NCP11 override
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/familyX/content/test/shout.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/data/familyX/content/test/shout.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Shout out!
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/familyX/prodX/confml/data.confml
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/familyX/prodX/content/prodX/jee/ProdX_specific.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/data/familyX/prodX/content/prodX/jee/ProdX_specific.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+földska
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/familyX/prodX/root.confml
Binary file configurationengine/source/cone/storage/tests/data/familyX/prodX/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/familyX/root.confml
Binary file configurationengine/source/cone/storage/tests/data/familyX/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/morestuff.confml
Binary file configurationengine/source/cone/storage/tests/data/morestuff.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/onefile/test.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/platform/s60/content/test/override.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/data/platform/s60/content/test/override.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+S60 default
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/platform/s60/content/test/s60.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/data/platform/s60/content/test/s60.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+hey!!
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/platform/s60/implml/accessoryserver_1020505A.crml
Binary file configurationengine/source/cone/storage/tests/data/platform/s60/implml/accessoryserver_1020505A.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/platform/s60/implml/accesspoints_10008D3A.crml
Binary file configurationengine/source/cone/storage/tests/data/platform/s60/implml/accesspoints_10008D3A.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/platform/s60/implml/accesspoints_10008D3B.crml
Binary file configurationengine/source/cone/storage/tests/data/platform/s60/implml/accesspoints_10008D3B.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/platform/s60/implml/actionpriorities_2000FDC2.crml
Binary file configurationengine/source/cone/storage/tests/data/platform/s60/implml/actionpriorities_2000FDC2.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/platform/s60/root.confml
Binary file configurationengine/source/cone/storage/tests/data/platform/s60/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/prodX.confml
Binary file configurationengine/source/cone/storage/tests/data/prodX.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/regional/japan/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/data/regional/japan/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/data/simple.confml
Binary file configurationengine/source/cone/storage/tests/data/simple.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/empty_zip_storage.zip
Binary file configurationengine/source/cone/storage/tests/empty_zip_storage.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/file_vs_zip_data.zip
Binary file configurationengine/source/cone/storage/tests/file_vs_zip_data.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/image-bmp-1bit.bmp
Binary file configurationengine/source/cone/storage/tests/fileres_test/image-bmp-1bit.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/image-bmp-24bit.bmp
Binary file configurationengine/source/cone/storage/tests/fileres_test/image-bmp-24bit.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/image-bmp-4bit.bmp
Binary file configurationengine/source/cone/storage/tests/fileres_test/image-bmp-4bit.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/image-bmp-8bit.bmp
Binary file configurationengine/source/cone/storage/tests/fileres_test/image-bmp-8bit.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/image-jpeg-1bit.jpg
Binary file configurationengine/source/cone/storage/tests/fileres_test/image-jpeg-1bit.jpg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/invalid.bmp
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/largefile.bin
Binary file configurationengine/source/cone/storage/tests/fileres_test/largefile.bin has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/fileres_test/testread.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/fileres_test/testread.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+foo bar test.
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/list_resources_data/7zip.zip
Binary file configurationengine/source/cone/storage/tests/list_resources_data/7zip.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/list_resources_data/carbide.ct.cpf
Binary file configurationengine/source/cone/storage/tests/list_resources_data/carbide.ct.cpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/list_resources_data/winzip.zip
Binary file configurationengine/source/cone/storage/tests/list_resources_data/winzip.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/simplewebserver.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/simplewebserver.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,169 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import SimpleHTTPServer
+import SocketServer
+import threading
+import httplib
+import os
+import simplejson
+import urllib
+import urlparse
+import posixpath
+import cgi
+from StringIO import StringIO
+
+class SimpleWebHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+ def __init__(self, request, client_address, server):
+ SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
+ self.action = ''
+
+ def send_head(self):
+ """Common code for GET and HEAD commands.
+
+ This sends the response code and MIME headers.
+
+ Return value is either a file object (which has to be copied
+ to the outputfile by the caller unless the command was HEAD,
+ and must be closed by the caller under all circumstances), or
+ None, in which case the caller has nothing further to do.
+
+ """
+ (action,path) = self.translate_path(self.path)
+
+ if action == 'list_resources':
+ return self.list_directory(path)
+ elif action == 'get_resource':
+ return self.get_resource(path)
+ else:
+ self.send_error(404, "File not found")
+ return None
+
+ def get_resource(self,path):
+ f = None
+ ctype = self.guess_type(path)
+ if ctype.startswith('text/'):
+ mode = 'r'
+ else:
+ mode = 'rb'
+ try:
+ f = open(path, mode)
+ except IOError:
+ self.send_error(404, "File not found")
+ return None
+ self.send_response(200)
+ self.send_header("Content-type", ctype)
+ fs = os.fstat(f.fileno())
+ self.send_header("Content-Length", str(fs[6]))
+ self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
+ self.end_headers()
+ return f
+
+ def list_directory(self, path):
+ """Helper to produce a directory listing (absent index.html).
+
+ Return value is either a file object, or None (indicating an
+ error). In either case, the headers are sent, making the
+ interface the same as for send_head().
+
+ """
+ try:
+ list = os.listdir(path)
+ except os.error:
+ self.send_error(404, "No permission to list directory")
+ return None
+ list.sort(key=lambda a: a.lower())
+ f = StringIO()
+ displaypath = cgi.escape(urllib.unquote(self.path))
+ files = []
+ for name in list:
+ fullname = os.path.join(path, name)
+ displayname = linkname = name
+ # Append / for directories or @ for symbolic links
+ if os.path.isdir(fullname):
+ displayname = name + "/"
+ linkname = name + "/"
+ if os.path.islink(fullname):
+ displayname = name + "@"
+ # Note: a link to a directory displays with @ and links with /
+ files.append(displayname)
+
+ f.write(simplejson.dumps(files))
+ length = f.tell()
+ f.seek(0)
+ self.send_response(200)
+ self.send_header("Content-type", "text/html")
+ self.send_header("Content-Length", str(length))
+ self.end_headers()
+ return f
+
+ def translate_path(self, path):
+ """Translate a /-separated PATH to the local filename syntax.
+
+ Components that mean special things to the local file system
+ (e.g. drive or directory names) are ignored. (XXX They should
+ probably be diagnosed.)
+ @return: action,path
+ """
+ # abandon query parameters
+ action = ''
+ path = urlparse.urlparse(path)[2]
+ path = path.lstrip('/')
+ splittedpath = path.split('/')
+ if len(splittedpath) > 1:
+ action = splittedpath[1]
+ path = "/".join(splittedpath[2:])
+ path = posixpath.normpath(urllib.unquote(path))
+ words = path.split('/')
+ words = filter(None, words)
+ path = os.getcwd()
+ for word in words:
+ drive, word = os.path.splitdrive(word)
+ head, word = os.path.split(word)
+ if word in (os.curdir, os.pardir): continue
+ path = os.path.join(path, word)
+ return (action,path)
+
+
+class SimpleWebServer(threading.Thread):
+ def __init__(self, folder=".", port=8000):
+ super(SimpleWebServer,self).__init__()
+ self.PORT = port
+ self.folder = folder
+ self.handler = SimpleWebHandler
+ self.httpd = SocketServer.TCPServer(("localhost", self.PORT), self.handler)
+ self.active = False
+ print "serving at port", self.PORT
+
+ def run(self):
+ # minimal web server. serves files relative to the
+ # current directory.
+ os.chdir(self.folder)
+ self.active = True
+ while self.active:
+ self.httpd.handle_request()
+ return 0
+
+ def stop(self):
+ self.active = False
+ conn = httplib.HTTPConnection('localhost', self.PORT)
+ conn.request("GET", "/")
+ r1 = conn.getresponse()
+ print r1.status, r1.reason
+
+if __name__ == '__main__':
+ server = SimpleWebServer()
+ server.start()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_fileresource.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_fileresource.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,162 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import zipfile
+import unittest
+import string
+import sys,os
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+import __init__
+from cone.public.exceptions import NotResource, StorageException
+from cone.public import api
+from cone.storage import filestorage
+
+
+class TestFileResource(unittest.TestCase):
+ def setUp(self):
+ self.spath = os.path.join(ROOT_PATH,"fileres_test")
+ self.storage = filestorage.FileStorage(self.spath)
+
+ def tearDown(self):
+ self.storage.close()
+
+ def test_open_and_write_resource(self):
+ res = self.storage.open_resource("testwrite.txt","w")
+ res.write("Testing writing func!")
+ res.close()
+ f = open(self.spath+"/testwrite.txt","r")
+ data = f.read()
+ self.assertEquals(data,"Testing writing func!")
+ f.close()
+ os.unlink(os.path.join(ROOT_PATH,"fileres_test/testwrite.txt"))
+
+ def test_open_and_read_resource(self):
+ res = self.storage.open_resource("testread.txt","r")
+ resdata = res.read()
+ res.close()
+ f = open(self.spath+"/testread.txt","r")
+ data = f.read()
+ f.close()
+ self.assertEquals(data,resdata)
+
+ def test_open_and_write_resource_and_trunk_it(self):
+ res = self.storage.open_resource("testtrunk.txt","w")
+ res.write("Testing writing func!")
+ res.truncate()
+ res.close()
+ f = open(self.spath+"/testtrunk.txt","r")
+ data = f.read()
+ self.assertEquals(data,"")
+ f.close()
+ os.unlink(os.path.join(ROOT_PATH,"fileres_test/testtrunk.txt"))
+
+ def test_get_size(self):
+ res = self.storage.open_resource("testread.txt", "r")
+ self.assertEquals(res.get_size(), 15)
+ # Try a second time just in case
+ self.assertEquals(res.get_size(), 15)
+ res.close()
+
+ def test_get_size_largefile(self):
+ res = self.storage.open_resource("largefile.bin", "r")
+ self.assertEquals(res.get_size(), 25000)
+ # Try a second time just in case
+ self.assertEquals(res.get_size(), 25000)
+ res.close()
+
+ def test_get_size_fails_in_write_mode(self):
+ res = self.storage.open_resource("test_getsize.txt","w")
+ res.write("Writing foobar")
+ self.assertRaises(StorageException, res.get_size)
+ res.close()
+
+ def test_bmp_content_info_24bit(self):
+ res = self.storage.open_resource("image-bmp-24bit.bmp", "r")
+ content_info = res.get_content_info()
+ self.assertEquals(api.BmpImageContentInfo, type(content_info))
+ self.assertEquals(24, res.get_content_info().color_depth)
+ self.assertEquals(24, content_info.color_depth)
+ self.assertEquals('image', content_info.mimetype)
+ self.assertEquals('bmp', content_info.mimesubtype)
+ self.assertEquals('image/bmp', content_info.content_type)
+ res.close()
+
+ def test_bmp_content_info_8bit(self):
+ res = self.storage.open_resource("image-bmp-8bit.bmp", "r")
+ content_info = res.get_content_info()
+ self.assertEquals(api.BmpImageContentInfo, type(content_info))
+ self.assertEquals(8, res.get_content_info().color_depth)
+ self.assertEquals(8, content_info.color_depth)
+ self.assertEquals('image', content_info.mimetype)
+ self.assertEquals('bmp', content_info.mimesubtype)
+ self.assertEquals('image/bmp', content_info.content_type)
+ res.close()
+
+ def test_bmp_content_info_4bit(self):
+ res = self.storage.open_resource("image-bmp-4bit.bmp", "r")
+ content_info = res.get_content_info()
+ self.assertEquals(api.BmpImageContentInfo, type(content_info))
+ self.assertEquals(4, res.get_content_info().color_depth)
+ self.assertEquals(4, content_info.color_depth)
+ self.assertEquals('image', content_info.mimetype)
+ self.assertEquals('bmp', content_info.mimesubtype)
+ self.assertEquals('image/bmp', content_info.content_type)
+ res.close()
+
+ def test_bmp_content_info_1bit(self):
+ res = self.storage.open_resource("image-bmp-1bit.bmp", "r")
+ content_info = res.get_content_info()
+ self.assertEquals(api.BmpImageContentInfo, type(content_info))
+ self.assertEquals(1, res.get_content_info().color_depth)
+ self.assertEquals(1, content_info.color_depth)
+ self.assertEquals('image', content_info.mimetype)
+ self.assertEquals('bmp', content_info.mimesubtype)
+ self.assertEquals('image/bmp', content_info.content_type)
+ res.close()
+
+ def test_content_info_with_jpg(self):
+ res = self.storage.open_resource("image-jpeg-1bit.jpg", "r")
+ content_info = res.get_content_info()
+ self.assertEquals('image/jpeg', content_info.content_type)
+ self.assertEquals('image', content_info.mimetype)
+ self.assertEquals('jpeg', content_info.mimesubtype)
+ res.close()
+
+
+ def test_content_info_invalid_bmp(self):
+ res = self.storage.open_resource("invalid.bmp", "r")
+ content_info = res.get_content_info()
+ self.assertEquals('image/bmp', content_info.content_type)
+ self.assertEquals('image', content_info.mimetype)
+ self.assertEquals('bmp', content_info.mimesubtype)
+ res.close()
+
+ def test_get_content_info_and_read_data(self):
+ res = self.storage.open_resource("testread.txt", "r")
+ ci = res.get_content_info()
+ self.assertEquals('text/plain', ci.content_type)
+ data = res.read()
+ self.assertEquals('foo bar test.\n', data)
+ res.close()
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_filestorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_filestorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,161 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import zipfile
+import unittest
+import string
+import sys,os,shutil
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+import __init__
+from cone.public.exceptions import NotResource,StorageException
+from cone.public import api
+from cone.storage import filestorage
+
+datafolder= ROOT_PATH
+datazip = os.path.join(ROOT_PATH,"data.zip")
+datafolder= os.path.join(ROOT_PATH,"data")
+
+
+class TestFileStorageCreation(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_create_storage_on_non_existing_path_fails(self):
+ try:
+ storage = filestorage.FileStorage("dummydatafolder")
+ self.fail("opening on dummydatafolder succeeds?")
+ except StorageException,e:
+ self.assertTrue(True)
+
+ def test_create_storage_on_file_fails(self):
+ try:
+ storage = filestorage.FileStorage(datazip)
+ self.fail("opening on data file succeeds?")
+ except StorageException,e:
+ self.assertTrue(True)
+
+ def test_create_storage_on_new_directory(self):
+ storage = filestorage.FileStorage("dummytest/storage","w")
+ self.assertTrue(os.path.exists("dummytest/storage"))
+ shutil.rmtree("dummytest")
+
+class TestFileStorage(unittest.TestCase):
+ def setUp(self):
+ self.storage = filestorage.FileStorage(datafolder)
+
+ def test_supported_storage(self):
+ self.assertTrue(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir/cone_vs_ct2/pf7132_020.006/config_project/"))
+ self.assertTrue(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir"))
+ self.assertFalse(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir.zip"))
+
+ def test_open_resource_existing_file_for_reading(self):
+ res = self.storage.open_resource("simple.confml")
+ self.assertTrue(res)
+ self.assertTrue(isinstance(res,api.Resource))
+
+ def test_open_resource_new_file(self):
+ res = self.storage.open_resource("newfile.txt","w")
+ self.assertTrue(res)
+ self.assertTrue(isinstance(res,api.Resource))
+ res.close()
+ self.assertTrue(os.path.exists(datafolder+"/newfile.txt"))
+ os.remove(datafolder+"/newfile.txt")
+
+ def test_list_resources(self):
+ self.assertEquals(self.storage.list_resources("."),
+ ['.metadata', 'morestuff.confml', 'prodX.confml', 'simple.confml'])
+
+ def test_delete_resource(self):
+ tf = open(os.path.join(datafolder,"tempfile.txt"),"w")
+ tf.close()
+ res = self.storage.delete_resource("tempfile.txt")
+ self.assertFalse(os.path.exists(datafolder+"tempfile.txt"))
+
+ def test_open_resource_nonexisting(self):
+ try:
+ res = self.storage.open_resource("iamnothere.txt")
+ self.fail("Opening of a non existing file succeeds!??")
+ except NotResource:
+ self.assertTrue(True)
+
+ def test_list_resources_nonrecurse(self):
+ file_array = self.storage.list_resources("")
+ self.assertEquals(file_array[0],".metadata")
+
+ def test_list_resources_nonrecurse_from_root(self):
+ file_array = self.storage.list_resources("/")
+ self.assertTrue(file_array.index(".metadata")==0)
+
+ def test_list_resources_recurse_from_root(self):
+ file_array = self.storage.list_resources("",True)
+ self.assertEquals(file_array[0],".metadata")
+
+ def test_list_resources_from_subfolder(self):
+ file_array = self.storage.list_resources("familyX")
+ self.assertEquals(file_array[0],"familyX/root.confml")
+
+ def test_list_resources_recurse_from_subfolder(self):
+ file_array = self.storage.list_resources("familyX", True)
+ self.assertEquals(file_array[0],"familyX/root.confml")
+ # Count only non-SVN files
+ self.assertEquals(len(filter(lambda x: x.find('.svn') == -1, file_array)), 7)
+
+ def test_is_resource_true(self):
+ self.assertTrue(self.storage.is_resource("simple.confml"))
+
+ def test_is_resource_true_with_begin_slash(self):
+ self.assertTrue(self.storage.is_resource("/simple.confml"))
+
+ def test_is_resource_false(self):
+ self.assertFalse(self.storage.is_resource("data"))
+
+ def test_open_resource_existing_file_with_root(self):
+ res = self.storage.open_resource("/simple.confml")
+ self.assertTrue(res)
+ self.assertTrue(isinstance(res,api.Resource))
+
+ def test_metadata_writing(self):
+ fs = filestorage.FileStorage("testtemp","w")
+ fs.set_active_configuration('testing.confml')
+ fs.close()
+ fs = filestorage.FileStorage("testtemp","r")
+ self.assertEquals(fs.get_active_configuration(),'testing.confml')
+ fs.close()
+ shutil.rmtree("testtemp")
+
+ def test_create_folder(self):
+ store = filestorage.FileStorage("newtestfolder","w")
+ store.create_folder("subdir")
+ self.assertTrue(store.is_folder("subdir"))
+ self.assertTrue(os.path.exists("newtestfolder/subdir"))
+ store.create_folder('foo')
+ layer = api.Folder(store, "foo")
+ self.assertTrue(store.is_folder("foo"))
+ self.assertTrue(layer)
+ self.assertTrue(os.path.exists("newtestfolder/subdir"))
+ layer.create_folder("foosubdir")
+ self.assertTrue(store.is_folder("foo/foosubdir"))
+ self.assertTrue(os.path.exists("newtestfolder/foo/foosubdir"))
+ shutil.rmtree('newtestfolder')
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_filestorage_layer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_filestorage_layer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,154 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys,os, shutil
+import __init__
+
+from cone.public import api,exceptions,utils
+from cone.storage import filestorage
+
+class TestLayer(unittest.TestCase):
+ storage_class = filestorage.FileStorage
+
+ def test_create_layer(self):
+ store = self.storage_class("temp/layertest","w")
+ layer = api.Layer(store, "foo")
+ self.assertTrue(layer)
+ shutil.rmtree("temp/layertest")
+
+# def test_create_layer_with_kwargs(self):
+# store = self.storage_class("temp/layertest","w")
+# layer = api.Layer(store, "foo",confml_path="foobar", implml_path="")
+# self.assertTrue(layer)
+# self.assertEquals(layer.confml_folder.get_current_path(),"foo/foobar")
+# self.assertEquals(layer.implml_folder.get_current_path(),"foo")
+# layer = api.Layer(store, "foo",confml_path="f", implml_path="test", content_path="data", doc_path="foo")
+# self.assertEquals(layer.confml_folder.get_current_path(),"foo/f")
+# self.assertEquals(layer.implml_folder.get_current_path(),"foo/test")
+# self.assertEquals(layer.content_folder.get_current_path(),"foo/data")
+# self.assertEquals(layer.doc_folder.get_current_path(),"foo/foo")
+# layer = api.Layer(store, "foo")
+# self.assertEquals(layer.confml_folder.get_current_path(),"foo/confml")
+# self.assertEquals(layer.implml_folder.get_current_path(),"foo/implml")
+# self.assertEquals(layer.content_folder.get_current_path(),"foo/content")
+# self.assertEquals(layer.doc_folder.get_current_path(),"foo/doc")
+# shutil.rmtree("temp/layertest")
+
+ def test_get_path(self):
+ store = self.storage_class("temp/layertest","w")
+ layer = api.Layer(store, "foo")
+ self.assertTrue(layer)
+ self.assertEquals(layer.get_current_path(),"foo")
+ shutil.rmtree("temp/layertest")
+
+ def test_open_resource(self):
+ store = self.storage_class("temp/layertest","w")
+ layer = api.Layer(store, "foo")
+ self.assertTrue(layer)
+ res = layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_resources("", True),["confml/test.confml"])
+ self.assertEquals(store.list_resources("", True),["foo/confml/test.confml"])
+ shutil.rmtree("temp/layertest")
+
+ def test_create_two_layers_and_open_resource(self):
+ store = self.storage_class("temp/layertest","w")
+ foo_layer = api.Layer(store, "foo")
+ bar_layer = api.Layer(store, "bar")
+ res = foo_layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = foo_layer.open_resource("root.confml","w")
+ res.close()
+ res = bar_layer.open_resource("confml/root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(foo_layer.list_resources("", True),['root.confml', 'confml/test.confml'])
+ self.assertEquals(store.list_resources("", True),['bar/confml/root.confml','foo/root.confml','foo/confml/test.confml'])
+ foo_layer.delete_resource("confml/test.confml")
+ self.assertEquals(foo_layer.list_resources("", True),["root.confml"])
+ self.assertEquals(store.list_resources("", True),["bar/confml/root.confml","foo/root.confml"])
+ shutil.rmtree("temp/layertest")
+
+ def test_list_confml(self):
+ store = self.storage_class("temp/layertest","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("confml/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_confml(),['confml/foo.confml', 'confml/test.confml'])
+ shutil.rmtree("temp/layertest")
+
+ def test_list_implml(self):
+ store = self.storage_class("temp/layertest","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("implml/stuff/test.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("confml/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_implml(),['implml/stuff/test.confml'])
+ shutil.rmtree("temp/layertest")
+
+ def test_list_content(self):
+ store = self.storage_class("temp/layertest","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("content/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("content/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_content(),['content/foo.confml', 'content/bar/test.txt'])
+ shutil.rmtree("temp/layertest")
+
+ def test_list_doc(self):
+ store = self.storage_class("temp/layertest","w")
+ layer = api.Layer(store, "foo")
+ res = layer.open_resource("doc/bar/test.txt","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("doc/foo.confml","w")
+ res.write("foo.conf")
+ res.close()
+ res = layer.open_resource("root.confml","w")
+ res.write("foo.conf")
+ res.close()
+ self.assertEquals(layer.list_doc(),['doc/foo.confml', 'doc/bar/test.txt'])
+ shutil.rmtree("temp/layertest")
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,186 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the import export functionality
+"""
+
+import unittest
+import sys, os, shutil
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from cone.public.api import Resource
+from cone.storage import filestorage, zipstorage
+
+from testautomation.base_testcase import BaseTestCase
+from testautomation.unzip_file import unzip_file
+
+def abspath(p):
+ return os.path.normpath(os.path.join(ROOT_PATH, p))
+
+DATA_ZIP = abspath("file_vs_zip_data.zip")
+TEMP_DIR = abspath("temp/file_vs_zip")
+
+EXPECTED = [
+ # These two are not used every time
+ ('folder', 'dir'),
+ ('folder', 'empty2'),
+
+ ('folder', 'dir/emptysub'),
+ ('folder', 'empty'),
+ ('folder', 'empty2/sub'),
+ ('resource', 'root.txt'),
+ ('resource', 'dir/test1.txt'),
+ ('resource', 'dir/test2.txt'),
+]
+
+class TestFileStorageVsZipStorage(BaseTestCase):
+ def setUp(self):
+ pass
+
+ def get_temp_zip_storage(self, path, empty=False):
+ """
+ Get a new zip storage located in the temp/ directory.
+
+ @param path: Path of the storage zip file relative to the temp/ directory.
+ @param empty: If False, the DATA_ZIP is copied to the location specified
+ by 'path' and returned as a read-only storage. If True, a new writable
+ empty storage is returned.
+ """
+ full_path = os.path.join(TEMP_DIR, path)
+ if not empty:
+ self.create_dir_for_file_path(full_path)
+ shutil.copy2(DATA_ZIP, full_path)
+ return zipstorage.ZipStorage(full_path, 'r')
+ else:
+ if os.path.exists(full_path):
+ os.remove(full_path)
+ return zipstorage.ZipStorage(full_path, 'w')
+
+ def get_temp_file_storage(self, path, empty=False):
+ """
+ Get a new file storage located in the temp/ directory.
+
+ @param path: Path of the storage directory relative to the temp/ directory.
+ @param empty: If False, the DATA_ZIP is extracted to the location specified
+ by 'path' and returned as a read-only storage. If True, a new writable
+ empty storage is returned.
+ """
+ full_path = os.path.join(TEMP_DIR, path)
+ if not empty:
+ unzip_file(DATA_ZIP, full_path, delete_if_exists=True)
+ return filestorage.FileStorage(full_path, 'r')
+ else:
+ self.recreate_dir(full_path)
+ return filestorage.FileStorage(full_path, 'w')
+
+ def assert_storage_contains_expected(self, storage, empty_folders):
+ # Always list also empty folders, because empty_folders is False,
+ # they should not have been exported in the first place
+ resource_list = storage.list_resources('', recurse=True, empty_folders=True)
+
+ expected = list(EXPECTED)
+
+ # Remove empty folders from expected if necessary
+ if not empty_folders:
+ for i in reversed(xrange(len(expected))):
+ if expected[i][0] == 'folder':
+ del expected[i]
+
+ # If the actual list contains exactly 2 less entries, they are
+ # probably the root folders that are not present in every case
+ # (e.g. there is a resource 'my_dir/file.txt', so sometimes there
+ # is a folder 'my_dir' in the resource list, but not always)
+ if len(resource_list) == len(expected) - 2:
+ del expected[0:2]
+
+ # Check that there is the same amount of resources/folders
+ self.assertEquals(len(expected), len(resource_list), "Expected %r, actual %r" % (expected, resource_list))
+
+ # Check that all expected resources/folders are present in the storage
+ for type, ref in expected:
+ if type == 'resource':
+ self.assertTrue(storage.is_resource(ref), "(%r, %r) expected, but not a resource" % (type, ref))
+ elif type == 'folder':
+ self.assertTrue(storage.is_folder(ref), "(%r, %r) expected, but not a folder" % (type, ref))
+ else:
+ raise RuntimeError("Invalid type field in expected data")
+
+ def _run_test_storage_to_storage(self, source_storage, target_storage, empty_folders):
+ try:
+ # Check that the source storage contains all expected in the first place
+ self.assert_storage_contains_expected(source_storage, True)
+
+ # Export resources
+ resources = source_storage.list_resources('', recurse=True, empty_folders=empty_folders)
+ source_storage.export_resources(resources, target_storage, empty_folders=empty_folders)
+
+ # Check that resources have been exported properly
+ self.assert_storage_contains_expected(target_storage, empty_folders)
+ finally:
+ source_storage.close()
+ target_storage.close()
+
+ def test_export_file_to_file(self):
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_file_storage('f2f/source'),
+ target_storage = self.get_temp_file_storage('f2f/target', empty=True),
+ empty_folders = False)
+
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_file_storage('f2f/ef_source'),
+ target_storage = self.get_temp_file_storage('f2f/ef_target', empty=True),
+ empty_folders = True)
+
+ def test_export_zip_to_zip(self):
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_zip_storage('z2z/source.zip'),
+ target_storage = self.get_temp_zip_storage('z2z/target.zip', empty=True),
+ empty_folders = False)
+
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_zip_storage('z2z/ef_source.zip'),
+ target_storage = self.get_temp_zip_storage('z2z/ef_target.zip', empty=True),
+ empty_folders = True)
+
+ def test_export_zip_to_file(self):
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_zip_storage('z2f/source.zip'),
+ target_storage = self.get_temp_file_storage('z2f/target', empty=True),
+ empty_folders = False)
+
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_zip_storage('z2f/ef_source.zip'),
+ target_storage = self.get_temp_file_storage('z2f/ef_target', empty=True),
+ empty_folders = True)
+
+ def test_export_file_to_zip(self):
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_file_storage('f2z/source'),
+ target_storage = self.get_temp_zip_storage('f2z/target.zip', empty=True),
+ empty_folders = False)
+
+ self._run_test_storage_to_storage(
+ source_storage = self.get_temp_file_storage('f2z/ef_source'),
+ target_storage = self.get_temp_zip_storage('f2z/ef_target.zip', empty=True),
+ empty_folders = True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_metadata.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_metadata.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,153 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the CPF metadata file parsing routines
+"""
+import os, sys, unittest
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.public import utils, exceptions, api
+from cone.storage import metadata, stringstorage
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+emptytestdata = ''\
+' '
+
+
+testdata = \
+''\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+
+class TestMetadataReader(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_create_meta_fromstring(self):
+ m = metadata.MetadataReader().fromstring(testdata)
+ self.assertTrue(m)
+
+ def test_create_meta_fromstring(self):
+ m = metadata.MetadataReader().fromstring(testdata)
+ self.assertTrue(m.data.has_key('cpf.name'))
+ self.assertTrue(m.data.has_key('cpf.description'))
+ self.assertTrue(m.data.has_key('cpf.viewId'))
+ self.assertTrue(m.data.has_key('cpf.rootFile'))
+ self.assertEquals(m.data['cpf.name'], 'test')
+ self.assertEquals(m.data['cpf.description'], 'just testing')
+ self.assertEquals(m.data['cpf.viewId'], 'Sample View')
+ self.assertEquals(m.data['cpf.rootFile'], 'root.confml')
+
+ def test_str_to_meta_and_back(self):
+ meta = metadata.MetadataReader().fromstring(testdata)
+ str = metadata.MetadataWriter().tostring(meta,False)
+ self.assertTrue(str.find('cpf.name'))
+
+ def test_get_property(self):
+ etree = ElementTree.fromstring(' ')
+ (key,value) = metadata.MetadataReader().get_property(etree)
+ self.assertEquals(key,'test')
+ self.assertEquals(value,'test')
+
+ def test_get_property_with_only_key(self):
+ etree = ElementTree.fromstring(' ')
+ (key,value) = metadata.MetadataReader().get_property(etree)
+ self.assertEquals(key,'test')
+ self.assertEquals(value,'')
+
+class TestMetadataWriter(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_metadata_tostring(self):
+ meta = metadata.Metadata()
+ str = metadata.MetadataWriter().tostring(meta)
+ self.assertTrue(str,emptytestdata)
+
+ def test_metadata_with_values_tostring(self):
+ meta = metadata.Metadata()
+ meta.data['cpf.name'] = 'testing ss'
+ meta.data['cpf.description'] = 'foo faa'
+ str = metadata.MetadataWriter().tostring(meta)
+ self.assertTrue(str,' ')
+
+ def test_metadata_with_values_to_resource(self):
+ meta = metadata.Metadata()
+ meta.data['cpf.name'] = 'testing ss'
+ meta.data['cpf.description'] = 'foo faa'
+ storage = stringstorage.StringStorage("")
+ res = storage.open_resource(".metadata","w")
+ metadata.MetadataWriter().toresource(meta,res)
+ self.assertTrue(res.getvalue(),' ')
+
+ def test_metadata_from_meta_to_str_and_back(self):
+ meta = metadata.Metadata()
+ meta.data['cpf.name'] = 'testing ss'
+ meta.data['cpf.description'] = 'foo faa'
+ str = metadata.MetadataWriter().tostring(meta)
+ meta2 = metadata.MetadataReader().fromstring(str)
+ self.assertEqual(meta.data,meta2.data)
+
+ def test_incorrect_class_fails(self):
+ try:
+ class dummy:
+ pass
+ str = metadata.MetadataWriter().tostring(dummy())
+ self.fail("Writing dummy class succeeds!")
+ except exceptions.IncorrectClassError,e:
+ pass
+
+
+ def test_set_property(self):
+ elem = ElementTree.Element('property')
+ prop = metadata.MetadataWriter().set_property(elem,'test','foof')
+ self.assertTrue(prop.get('name'),'test')
+ self.assertTrue(prop.get('value'),'foof')
+
+ def test_set_property_with_only_key(self):
+ elem = ElementTree.Element('property')
+ prop = metadata.MetadataWriter().set_property(elem,'test','')
+ self.assertEquals(prop.get('name'),'test')
+ self.assertEquals(prop.get('value'),None)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_resource.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_resource.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test Respource
+"""
+import unittest
+import string
+import sys,os
+import __init__
+
+from cone.public.api import Resource
+from cone.storage.stringstorage import StringResource
+
+class TestResource(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_create_resource(self):
+ res = Resource("","",None)
+ self.assertTrue(res)
+
+class TestStringResource(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_create_stringresource_with_data(self):
+ res = StringResource("","","Test data")
+ self.assertTrue(res)
+ self.assertEqual(res.read(),"Test data")
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_stringstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_stringstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import string
+import sys,os
+import pickle
+import __init__
+
+from cone.public import api
+from cone.storage import stringstorage
+
+class TestStringStorage(unittest.TestCase):
+ def test_internal_add_and_list(self):
+ store = api.Storage.open("test.pk","w")
+ store._add_to_path("test.foo.bar",stringstorage._StringStorageObject("test1.txt"))
+ store._add_to_path("test.foo.bar",stringstorage._StringStorageObject("test2.txt"))
+ self.assertEquals(store._get("test.foo.bar")._list(),
+ ['test1',
+ 'test2'])
+ store.close()
+ os.unlink("test.pk")
+
+ def test_internal_add_get_and_list(self):
+ store = api.Storage.open("test.pk","w")
+ obj = stringstorage._StringStorageObject("test1.txt")
+ store._add_to_path("test.foo.bar",obj)
+ store._add_to_path("test.foo.bar",stringstorage._StringStorageObject("test2.txt"))
+ obj.data = "Fooo"
+ self.assertEquals(store._get("test.foo.bar")._list(),
+ ['test1',
+ 'test2'])
+ self.assertEquals(store.test.foo.bar.test1.data,'Fooo')
+ store.close()
+ os.unlink("test.pk")
+
+ def test_internal_add_get_and_list_all(self):
+ store = api.Storage.open("test.pk","w")
+ store._add_to_path("test.foo.bar",stringstorage._StringStorageObject("test1.txt"))
+ store._add_to_path("test.foo.bar",stringstorage._StringStorageObject("test2.txt"))
+ store._add(stringstorage._StringStorageObject("root.txt"))
+ self.assertEquals(store._list_traverse(type=stringstorage._StringStorageObject), ['test.foo.bar.test1',
+ 'test.foo.bar.test2',
+ 'root'])
+ store.close()
+ os.unlink("test.pk")
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_webstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_webstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,110 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import string
+import sys,os
+import pickle
+import time
+import __init__
+
+from cone.public import api, exceptions
+from cone.storage import webstorage
+from cone.carbon import model
+import simplewebserver
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TEST_SERVER = simplewebserver.SimpleWebServer(os.path.join(ROOT_PATH,'carbondata'), 8001)
+#
+#def runserver():
+# if not TEST_SERVER.active:
+# TEST_SERVER.start()
+# time.sleep(1)
+#
+#def stopserver():
+# if TEST_SERVER.active:
+# TEST_SERVER.stop()
+#
+#class TestWebStorage(unittest.TestCase):
+# def setUp(self):
+# runserver()
+#
+# def __del__(self):
+# stopserver()
+#
+# def test_create_web_storage(self):
+# store = webstorage.WebStorage('localhost:8001/extapp')
+#
+#
+# def test__get_stringio_from_path(self):
+# store = webstorage.WebStorage('localhost:8001/extapp')
+# strio = store._get_stringio_from_path('alvin.confml')
+# self.assertTrue(len(strio.getvalue()) > 0)
+#
+# def test__get_stringio_from_path_fails(self):
+#
+# store = webstorage.WebStorage('localhost:8001/extapp')
+# try:
+# strio = store._get_stringio_from_path('foobar.confml')
+# self.fail('Getting nonexistent file succeeds?')
+# except exceptions.NotResource:
+# pass
+#
+#
+# def test_get_resource_from_path(self):
+# store = webstorage.WebStorage('localhost:8001/extapp')
+# wres = store.open_resource('test/empty.confml')
+# self.assertTrue(len(wres.read()) == 0)
+#
+# def test_get_resource_fails(self):
+# store = webstorage.WebStorage('localhost:8001/extapp')
+# try:
+# wres = store.open_resource('foobar.confml')
+# self.fail('test')
+# except exceptions.NotResource:
+# pass
+
+class TestResourceCache(unittest.TestCase):
+# def test_create_resource_cache_add_configurations(self):
+# rc = webstorage.ResourceCache()
+# conf = model.ConfigurationResource(**{'parent_config': 'hessu', 'path': 'NCP/Testing', 'version_identifier': '0.1', 'configuration_name': 'Testing'})
+# rc.add_configuration(conf)
+# self.assertEquals(rc.list_resources('/'), ['Testing.confml'])
+# self.assertEquals(rc.list_resources('/', True), ['Testing.confml', 'NCP/Testing/root.confml'])
+# self.assertEquals(rc.get_resource('Testing.confml').name, 'Testing_confml')
+# self.assertEquals(isinstance(rc.get_resource('Testing.confml'),model.CarbonConfiguration),True)
+# self.assertEquals(rc.get_resource('Testing.confml').list_configurations(),['NCP/Testing/root.confml'])
+
+ def test_create_resource_cache_from_resource_list(self):
+ reslist = ['test.configurationroot',
+ 'test.configurationlayer',
+ 'test.featurelist']
+ rc = webstorage.ResourceCache()
+ for res in reslist:
+ rc.add_resource(res)
+ self.assertEquals(rc.list_resources('/'), ['test.confml'])
+ self.assertEquals(rc.list_resources('/', True), ['test/root.confml',
+ 'featurelists/test.confml',
+ 'test.confml'])
+ self.assertEquals(rc.get_resource_link('test.confml'), 'test.configurationroot')
+ self.assertEquals(rc.get_resource_link('featurelists/test.confml'), 'test.featurelist')
+ self.assertEquals(rc.get_resource_link('test/root.confml'), 'test.configurationlayer')
+
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_webstorage_carbon.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_webstorage_carbon.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,246 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import string
+import sys,os
+import pickle
+import time
+import __init__
+
+from cone.public import api, exceptions
+from cone.storage import webstorage
+from cone.carbon import model, persistentjson
+import simplewebserver
+
+featurelist = {
+ "featurelist": {
+ "features": [
+ {
+ "status": "APPROVED",
+ "value_type": "",
+ "description": "None",
+ "title": "TestGroup",
+ "ref": "testgroup",
+ "type": "featuregroup",
+ "id": 11749,
+ "children": [
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "None",
+ "title": "Child1",
+ "ref": "child1",
+ "type": "feature",
+ "id": 11750,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "None",
+ "title": "Child1",
+ "ref": "child1_1",
+ "type": "feature",
+ "id": 11751,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "None",
+ "title": "Child1",
+ "ref": "child1_2",
+ "type": "feature",
+ "id": 11753,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "Needs description",
+ "title": "Child1",
+ "ref": "child1_3",
+ "type": "feature",
+ "id": 11756,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "Needs description",
+ "title": "Child1",
+ "ref": "child1_4",
+ "type": "feature",
+ "id": 11759,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "None",
+ "title": "Child2",
+ "ref": "child2",
+ "type": "feature",
+ "id": 11754,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "Needs description",
+ "title": "Child2",
+ "ref": "child2_1",
+ "type": "feature",
+ "id": 11757,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "boolean",
+ "description": "Needs description",
+ "title": "Child2",
+ "ref": "child2_2",
+ "type": "feature",
+ "id": 11760,
+ "children": []
+ }
+ ]
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "",
+ "description": "Needs description",
+ "title": "TestGroup",
+ "ref": "testgroup_3",
+ "type": "featuregroup",
+ "id": 11758,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "",
+ "description": "None",
+ "title": "TestGroup",
+ "ref": "testgroup_1",
+ "type": "featuregroup",
+ "id": 11752,
+ "children": []
+ },
+ {
+ "status": "APPROVED",
+ "value_type": "",
+ "description": "Needs description",
+ "title": "TestGroup",
+ "ref": "testgroup_2",
+ "type": "featuregroup",
+ "id": 11755,
+ "children": []
+ }
+ ],
+ "list_version_id": 34,
+ "expanded": True,
+ "version_identifier": "WORKING",
+ "is_latest_version": True,
+ "list_id": 37,
+ "path": "TEST4",
+ "version_title": "TEST4 (WORKING)",
+ "can_be_released": True,
+ "type": "featurelist",
+ "has_external_relations": False
+ }
+}
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+#class TestWebStorage(unittest.TestCase):
+# def setUp(self):
+# self.store = webstorage.WebStorage('http://localhost:8000/extapi')
+#
+# def test_create_and_list_resources(self):
+# files = self.store.list_resources('/')
+# print files
+# self.assertTrue(len(files)>0)
+##
+# def test_create_and_list_resources_with_non_existing_folder(self):
+# files = self.store.list_resources('foo')
+# self.assertEquals(files,[])
+# files = self.store.list_resources('foo/')
+# self.assertEquals(files,[])
+# files = self.store.list_resources('foo/bar')
+# self.assertEquals(files,[])
+#
+# def test_get_resource(self):
+# res = self.store.open_resource('Zoom.confml')
+## resdata = res.read()
+## self.assertTrue(len(resdata) > 0)
+#
+# def test_get_resource_fails(self):
+# try:
+# res = self.store.open_resource('Zoomi.confml')
+# self.fail('Opening non existing resource succeeds')
+#
+# except exceptions.NotResource, e:
+# pass
+#
+# def test_is_resource(self):
+# ret = self.store.is_resource('Zoom.confml')
+# self.assertTrue(ret)
+#
+# def test_is_resource_false(self):
+# ret = self.store.is_resource('Foobar.confml')
+# self.assertFalse(ret)
+
+class TestCarbonExtapi(unittest.TestCase):
+ def setUp(self):
+ pass
+
+# def test_create_feature(self):
+# extapi = webstorage.CarbonExtapi('http://localhost:8000/extapi')
+# self.assertTrue(extapi.create_feature('TEST4.featurelist',model.CarbonSetting('TestGroup')))
+# self.assertTrue(extapi.create_feature('TEST4.featurelist',model.CarbonBooleanSetting('Child1'), 'TestGroup'))
+# self.assertTrue(extapi.create_feature('TEST4.featurelist',model.CarbonBooleanSetting('Child2'), 'TestGroup'))
+#
+# def test_create_feature_fails(self):
+# extapi = webstorage.CarbonExtapi('http://localhost:8000/extapi')
+# self.assertFalse(extapi.create_feature('TEST4.featurelist',model.CarbonSetting('Foobar2'), 'TestGroup'))
+#
+# def test_create_featurelist(self):
+# extapi = webstorage.CarbonExtapi('http://localhost:8000/extapi')
+# self.assertTrue(extapi.create_featurelist('TEST.featurelist',model.FeatureList(name='TEST9')))
+
+# def test_update_featurelist(self):
+# extapi = webstorage.CarbonExtapi('http://localhost:8000/extapi', password='terytkone09')
+# fl = model.FeatureList(name='TEST9')
+# fl.add_feature(model.CarbonFeature('Test1'))
+# data = persistentjson.dumps(fl)
+# data = {"features" :[],
+# "version_identifier": "WORKING",
+# "flv_description": "Needs description",
+# "path": "TEST9.confml",
+# "type": "featurelist",
+# "name": "TEST9"}
+# print "data %s" % data
+# self.assertTrue(extapi.update_resource('TEST9.featurelist',data))
+
+# def test_create_configuration(self):
+# extapi = webstorage.CarbonExtapi('http://localhost:8000/extapi', password='terytkone09')
+# conf = model.CarbonConfiguration(path='Testing3.confml')
+# (success,conf)= extapi.create_configuration('Testing3.configuration',conf)
+# self.assertTrue(success)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_zipresource.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_zipresource.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,119 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import zipfile
+import unittest
+import string
+import sys,os,shutil
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+import __init__
+from cone.public.exceptions import *
+from cone.public.api import Resource
+from cone.storage import zipstorage
+
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp')
+tempzip = os.path.join(ROOT_PATH,"zipres_test.zip")
+
+
+class TestFileResource(unittest.TestCase):
+
+ def _prepare_tempzip(self, filename):
+ """
+ Prepare a temporary ZIP file with the given name.
+ @return: Absolute path to the newly copied ZIP file.
+ """
+ new_zip = os.path.join(TEMP_DIR, '%s' % filename)
+
+ if os.path.exists(new_zip):
+ os.unlink(new_zip)
+
+ if not os.path.exists(TEMP_DIR):
+ os.makedirs(TEMP_DIR)
+
+ shutil.copyfile(tempzip, new_zip)
+ return new_zip
+
+ def test_open_and_write_resource(self):
+ ZIPFILE = self._prepare_tempzip('test1.zip')
+ store = zipstorage.ZipStorage(ZIPFILE,"a")
+ res = store.open_resource("temp/testwrite.txt","w")
+ testdata = "Testing writing func!"
+ res.write(testdata)
+ res.close()
+ store.close()
+ zf = zipfile.ZipFile(ZIPFILE,"r")
+ data = zf.read("temp/testwrite.txt")
+ self.assertEquals(data,testdata)
+
+ def test_open_and_read_resource(self):
+ ZIPFILE = self._prepare_tempzip('test2.zip')
+ store = zipstorage.ZipStorage(ZIPFILE,"a")
+ res = store.open_resource("temp/testread.txt","r")
+ resdata = res.read()
+ res.close()
+ store.close()
+ self.assertTrue(resdata.startswith("Hello"))
+
+ def test_get_size(self):
+ ZIPFILE = self._prepare_tempzip('test_getsize.zip')
+ store = zipstorage.ZipStorage(ZIPFILE, "r")
+ res = store.open_resource("temp/testread.txt","r")
+ self.assertEquals(res.get_size(), 28)
+ # Try a second time just in case
+ self.assertEquals(res.get_size(), 28)
+ res.close()
+ store.close()
+
+ def test_get_size_largefile(self):
+ ZIPFILE = self._prepare_tempzip('test_getsize_largefile.zip')
+ store = zipstorage.ZipStorage(ZIPFILE, "r")
+ res = store.open_resource("largefile.bin","r")
+ self.assertEquals(res.get_size(), 25000)
+ # Try a second time just in case
+ self.assertEquals(res.get_size(), 25000)
+ res.close()
+ store.close()
+
+ def test_get_size_fails_in_write_mode(self):
+ ZIPFILE = os.path.join(TEMP_DIR, 'getsize_fails_in_write_mode.zip')
+ store = zipstorage.ZipStorage(ZIPFILE, "w")
+ res = store.open_resource("test_getsize.txt", "w")
+ res.write("Writing foobar")
+ self.assertRaises(StorageException, res.get_size)
+ res.close()
+ store.close()
+
+ def test_get_content_info_and_read_data(self):
+ ZIPFILE = self._prepare_tempzip('test2.zip')
+ store = zipstorage.ZipStorage(ZIPFILE,"a")
+ res = store.open_resource("temp/testread.txt","r")
+ ci = res.get_content_info()
+ self.assertEquals('text/plain', ci.content_type)
+ resdata = res.read()
+ self.assertEquals('Hello!\r\nHow is my reading?\r\n', resdata)
+ res.close()
+ store.close()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/unittest_zipstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_zipstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,255 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+"""
+Test the CPF root file parsing routines
+"""
+
+import zipfile
+import unittest
+import string
+import sys,os,shutil
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+import __init__
+from cone.public import exceptions, api
+from cone.storage import zipstorage
+
+datazip = os.path.join(ROOT_PATH,"data.zip")
+
+#class TestZipStorageDummy(unittest.TestCase):
+# def test_open_storage(self):
+# storage = zipstorage.ZipStorage("TestProlog.zip","r")
+# res = storage.open_resource("TestProlog")
+# storage.close()
+
+class TestZipStorage(unittest.TestCase):
+ def test_create_new_storage(self):
+ storage = zipstorage.ZipStorage("new.zip","w")
+ storage.close()
+ self.assertTrue(os.path.exists("new.zip"))
+ os.unlink("new.zip")
+
+ def test_open_existing_storage(self):
+ storage = zipstorage.ZipStorage(datazip,"r")
+ storage.close()
+
+ def test_open_existing_storage_and_close_twice(self):
+ storage = zipstorage.ZipStorage(datazip,"r")
+ storage.close()
+ try:
+ storage.close()
+ self.fail('closing twice succeeds!')
+ except exceptions.StorageException:
+ pass
+
+ def test_open_nonexisting_storage_fails(self):
+ try:
+ storage = zipstorage.ZipStorage("foo.zip","r")
+ storage.close()
+ self.fail("opening a non existing ZipStorage succeeded?")
+ except zipstorage.ZipException:
+ self.assertTrue(True)
+
+ def test_open_a_non_zipfile_fails(self):
+ try:
+ storage = zipstorage.ZipStorage("data/onefile/test.txt","r")
+ storage.close()
+ self.fail("opening a non zipfile for ZipStorage succeeded?")
+ except zipstorage.ZipException,e:
+ self.assertTrue(True)
+
+class TestStorage(unittest.TestCase):
+ def setUp(self):
+ shutil.copyfile(datazip,"temptests.zip")
+ self.storage = zipstorage.ZipStorage("temptests.zip","a")
+
+ def tearDown(self):
+ self.storage.close()
+ os.unlink("temptests.zip")
+
+ def test_open_resource_existing_file_for_reading(self):
+ res = self.storage.open_resource("data/simple.confml","w")
+ self.assertTrue(res)
+ self.assertTrue(isinstance(res,api.Resource))
+
+ def test_open_resource_new_file(self):
+ storage = zipstorage.ZipStorage("testnewfile.zip","w")
+ res = storage.open_resource("data/newfile.txt","w")
+ res.write("test write")
+ self.assertTrue(res)
+ self.assertTrue(isinstance(res,api.Resource))
+ res.close()
+ self.assertEquals(storage.list_resources("",True), ['data/newfile.txt'])
+ storage.close()
+ os.unlink("testnewfile.zip")
+
+
+ def test_open_resource_nonexisting(self):
+ try:
+ res = self.storage.open_resource("iamnothere.txt")
+ self.fail("Opening of a non existing file succeeds!??")
+ except exceptions.NotResource:
+ self.assertTrue(True)
+
+ def test_list_resources_nonrecurse(self):
+ storage = zipstorage.ZipStorage("testnonrecurse.zip","w")
+ res = storage.open_resource("data/morestuff.confml","w")
+ res.close()
+ res = storage.open_resource("data/prodX.confml","w")
+ res.close()
+ file_array = storage.list_resources("data")
+ self.assertEquals(file_array[0],"data/morestuff.confml")
+ self.assertEquals(file_array[1],"data/prodX.confml")
+ storage.close()
+ os.unlink("testnonrecurse.zip")
+
+ def test_list_resources_recurse(self):
+ storage = zipstorage.ZipStorage("testrecurse.zip","w")
+ res = storage.open_resource("data/foo/morestuff.confml","w")
+ res.close()
+ res = storage.open_resource("data/prodX.confml","w")
+ res.close()
+ res = storage.open_resource("data/ncp11/confml/jallaa.confml","w")
+ res.close()
+ file_array = storage.list_resources("data",True)
+ self.assertEquals(file_array,['data/foo/morestuff.confml', 'data/prodX.confml', 'data/ncp11/confml/jallaa.confml'])
+ storage.close()
+ os.unlink("testrecurse.zip")
+
+ def test_is_resource_true(self):
+ res = self.storage.open_resource("data/simple.confml","w")
+ res.close()
+ self.assertTrue(self.storage.is_resource("data/simple.confml"))
+
+ def test_is_resource_true_for_dotted_file(self):
+ res = self.storage.open_resource(".metadata","w")
+ res.close()
+ self.assertTrue(self.storage.is_resource(".metadata"))
+
+ def test_is_resource_true_with_slash(self):
+ res = self.storage.open_resource("data/simple.confml","w")
+ res.close()
+ self.assertTrue(self.storage.is_resource("/data/simple.confml"))
+
+ def test_is_resource_false(self):
+ self.assertFalse(self.storage.is_resource("data"))
+
+ def test_metadata_writing(self):
+ fs = zipstorage.ZipStorage("testtemp.zip","w")
+ fs.set_active_configuration('testing.confml')
+ fs.close()
+ fs = zipstorage.ZipStorage("testtemp.zip","r")
+ self.assertEquals(fs.get_active_configuration(),'testing.confml')
+ fs.close()
+ os.unlink("testtemp.zip")
+
+ def test_open_resource_new_file_and_overwrite(self):
+ storage = api.Storage.open("testoverwrite.zip","w")
+ res = storage.open_resource("data/newfile.txt","w")
+ res.write("test write")
+ self.assertTrue(res)
+ self.assertTrue(isinstance(res,api.Resource))
+ res.close()
+ res = storage.open_resource("data/newfile.txt","w")
+ res.write("Hahaaa")
+ res.close()
+ storage.close()
+ storage = api.Storage.open("testoverwrite.zip","r")
+ self.assertEquals(storage.open_resource("data/newfile.txt").read(), "Hahaaa")
+ storage.close()
+ os.unlink("testoverwrite.zip")
+
+ def test_delete_resource(self):
+ storage = api.Storage.open("testdelete.zip","w")
+ res = storage.open_resource("data/newfile.txt","w")
+ res.write("test write")
+ res.close()
+ res = storage.open_resource("readme.txt","w")
+ res.write("test 2")
+ res.close()
+ storage.close()
+ storage2 = api.Storage.open("testdelete.zip","a")
+ #self.assertEquals(storage2.list_resources("",True), ['.metadata', 'data/newfile.txt', 'readme.txt'])
+ self.assertEquals(storage2.open_resource("data/newfile.txt").read(),"test write")
+ storage2.delete_resource("data/newfile.txt")
+ self.assertEquals(len(storage2.list_resources("",True)),2)
+ storage2.close()
+ storage3 = api.Storage.open("testdelete.zip","a")
+ self.assertEquals(storage3.list_resources("",True), ['readme.txt','.metadata'])
+ storage3.close()
+ os.unlink("testdelete.zip")
+
+
+ def test_create_folder(self):
+ storage = api.Storage.open("empty_folder.zip","w")
+ res = storage.open_resource("test.txt","w")
+ res.write('test')
+ res.close()
+ storage.create_folder("data")
+ storage.create_folder("data2/folder1")
+ storage.create_folder("data3\\")
+ storage.close()
+
+ storage2 = api.Storage.open("empty_folder.zip","a")
+ self.assertEquals(storage2.is_folder("data"),True)
+ self.assertEquals(storage2.is_folder("data2/folder1"),True)
+ self.assertEquals(storage2.is_folder("data3"),True)
+ self.assertEquals(storage2.list_resources('.',True),['test.txt','.metadata'])
+ self.assertEquals(storage2.list_resources(''),['test.txt','.metadata'])
+ storage2.close()
+ os.unlink("empty_folder.zip")
+
+class TestZipStorageListResources(unittest.TestCase):
+
+ def _run_test_list_resources(self, zip_file):
+ full_path = os.path.join(ROOT_PATH, 'list_resources_data', zip_file)
+ zs = zipstorage.ZipStorage(full_path, 'r')
+ res_list = zs.list_resources('/', recurse=True, empty_folders=True)
+
+ expected = [
+ ('folder', 'test'),
+ ('folder', 'test/layer'),
+ ('folder', 'test/layer/confml'),
+ ('folder', 'test/layer/content'),
+ ('folder', 'test/layer/content/empty'),
+ ('folder', 'test/layer/content/something'),
+ ('resource', 'test/layer/content/something/x.txt'),
+ ('folder', 'test/layer/doc'),
+ ('folder', 'test/layer/implml'),
+ ('resource', 'test/layer/root.confml'),
+ ('resource', 'test/root.confml')]
+ for type, res in expected:
+ if type == 'resource':
+ self.assertTrue(zs.is_resource(res), "zs.is_resource('%s') returns False" % res)
+ elif type == 'folder':
+ self.assertTrue(zs.is_folder(res), "zs.is_folder('%s') returns False" % res)
+ else:
+ raise RuntimeError('Invalid type')
+
+ def test_list_resources_7zip_zipped(self):
+ self._run_test_list_resources('7zip.zip')
+
+ def test_list_resources_winzip_zipped(self):
+ self._run_test_list_resources('winzip.zip')
+
+ def test_list_resources_carbide_ct_zipped(self):
+ self._run_test_list_resources('carbide.ct.cpf')
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/zipres_test.zip
Binary file configurationengine/source/cone/storage/tests/zipres_test.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/webstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/webstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,621 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+import getpass
+import StringIO
+import os
+import re
+import copy
+import logging
+import httplib
+import urllib, urllib2
+import simplejson
+import posixpath
+
+from cone.public import *
+from cone.carbon import persistentjson, model
+from cone.storage import authenticate
+
+class WebStorage(api.Storage):
+ """
+ A general base class for all storage type classes
+ @param path : the reference to the root of the storage.
+ """
+
+ def __init__(self, path, mode="a", **kwargs):
+ api.Storage.__init__(self,path)
+ self.mode = mode
+ self.extapi = CarbonExtapi(path, **kwargs)
+ self.persistentmodule = persistentjson
+
+ # resource cache is a intermediate solution to create a mapping between carbon objects and Configuration project
+ self._resource_cache = None
+
+
+ def _create_resource(self, path, object):
+ """
+ Create a new resource (configuration|featurelist) to carbon storage.
+ """
+ # Test the path, whether it is a featurelist or configuration
+ try:
+ object_type = object.meta.get('type')
+ except (TypeError,AttributeError):
+ logging.getLogger('cone').error('Cannot dump configuration %s to webstorage without a type.' % path)
+ return False
+ carbonpath = persistentjson.CarbonResourceMapper().map_confml_resource(object_type, path)
+ if object_type == 'featurelist':
+ # Create a featurelist
+ success = self.extapi.create_featurelist(carbonpath, object)
+ if success:
+ self.resource_cache.add_resource_link(path, carbonpath)
+ return success
+ else:
+ # Create a configuration
+ success = self.extapi.create_configuration(carbonpath, object)
+ if success:
+ self.resource_cache.add_resource_link(path, carbonpath)
+ return success
+
+ @classmethod
+ def supported_storage(cls,path):
+ """
+ Class method for determing if the given clas supports a storage by given path.
+ E.g. http://foo.com/
+ @param path:
+ @return: Boolean value. True if the storage of the path is supported. False if not.
+ """
+ if path.startswith('http://'):
+ return True
+ else:
+ return False
+
+ @property
+ def resource_cache(self):
+ """
+ Returns a resource cache dictionary of all the resources inside the Carbon storage. Works as an intermediate
+ solution to link Configuration project concepts to Carbon storage
+
+ """
+ if not self._resource_cache:
+ self._resource_cache = ResourceCache()
+ reslist = self.extapi.list_resources("/", True)
+ # Append all resources to resource cache
+ for res in reslist:
+ self._resource_cache.add_resource(res)
+# if isinstance(res, model.ConfigurationResource):
+# self._resource_cache.add_configuration(res)
+# elif isinstance(res, model.FeatureListResource):
+# self._resource_cache.add_featurelist(res)
+ return self._resource_cache
+
+ def list_resources(self,path, recurse=False, empty_folders=False):
+ """
+ find the resources under certain path/path
+ @param path : reference to path where resources are searched
+ @param recurse : defines whether to return resources directly under the path or does the listing recurse to subfolders.
+ Default value is False. Set to True to enable recursion.
+ @param empty_folders: parameters that defined whether empty folders are included. This parameter is ignored
+ in WebStorage.
+ """
+ return self.resource_cache.list_resources(path,recurse)
+
+
+ def open_resource(self,path,mode="r"):
+ path = utils.resourceref.remove_begin_slash(path)
+ if self.resource_cache.get_resource_object(path):
+ return self.resource_cache.get_resource_object(path)
+ elif self.resource_cache.get_resource_link(path):
+ path = self.resource_cache.get_resource_link(path)
+
+# path = path.replace(".confml", ".configuration")
+# path = utils.resourceref.join_refs([self.get_current_path(), path])
+ try:
+ if self.get_mode(mode) == self.MODE_READ:
+ strio = self.extapi._get_stringio_from_path(path)
+ elif self.get_mode(mode) == self.MODE_APPEND:
+ strio = self.extapi._get_stringio_from_path(path)
+ strio.seek(0, os.SEEK_END)
+ elif self.get_mode(mode) == self.MODE_WRITE:
+ strio = StringIO.StringIO()
+ else:
+ raise StorageException("Unrecognized mode %s" % mode)
+ res = WebResource(self,path,mode,strio)
+ self.__opened__(res)
+ return res
+ except KeyError:
+ raise exceptions.NotResource("The given resource is not found %s" % path)
+
+ def is_resource(self,path):
+ return self.resource_cache.is_resource(path)
+# path = path.replace(".confml", ".configuration")
+# path = utils.resourceref.join_refs([self.get_current_path(), path])
+# try:
+# query = urllib.quote(self._get_action_url('is_resource', path))
+# self.conn.request("GET", query)
+# resp = self.conn.getresponse()
+# reader = persistentjson.HasResourceReader()
+# return reader.loads(resp.read())
+# except exceptions.NotFound:
+# return False
+
+ def save_resource(self, res):
+ """
+ Close resource is no-operation action with webstorage for now
+ """
+ return
+
+ def close_resource(self, path):
+ """
+ Close resource is no-operation action with webstorage
+ """
+ return
+
+ def export_resources(self, paths, storage, empty_folders=False):
+ for path in paths:
+ if not self.is_resource(path):
+ logging.getLogger('cone').warning("The given path is not a Resource in this storage %s! Ignoring from export!" % path)
+ continue
+ wres = storage.open_resource(path,'wb')
+ res = self.open_resource(path,"rb")
+ wres.write(res.read())
+ wres.close()
+ res.close()
+
+ def unload(self, path, object):
+ """
+ Dump a given object to the storage (reference is fetched from the object)
+ @param object: The object to dump to the storage, which is expected to be an instance
+ of Base class.
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ print "unload %s" % path
+ if not isinstance(object, api.Configuration):
+ raise exceptions.StorageException("Cannot dump object type %s" % object.__class__)
+ # Skip the unload storing to storage if the storage is opened in read mode
+ if self.get_mode(self.mode) != api.Storage.MODE_READ:
+ if self.resource_cache.get_resource_link(path):
+ path = self.resource_cache.get_resource_link(path)
+ else:
+ """ otherwise create the new resource first before update"""
+ if self._create_resource(path, object):
+ path = self.resource_cache.get_resource_link(path)
+ else:
+ # Creation failed
+ logging.getLogger('cone').error('Creation of %s resource failed' % path)
+ return
+ data = persistentjson.dumps(object)
+ self.extapi.update_resource(path, data)
+ else:
+ raise exceptions.StorageException("Cannot dump object to readonly storage")
+ return
+
+ def load(self, path):
+ """
+ Load resource from a path.
+ """
+ # Check if the object is already cached or has a cached link to another resource to load
+ path = utils.resourceref.remove_begin_slash(path)
+ print "load %s" % path
+ if self.resource_cache.get_resource_link(path):
+ path = self.resource_cache.get_resource_link(path)
+ elif self.resource_cache.get_mapped_resource(path):
+ path = self.resource_cache.get_mapped_resource(path)
+ elif not utils.resourceref.get_ext(path) == "confml":
+ raise exceptions.StorageException("Cannot load reference type %s" % utils.resourceref.get_ext(path))
+ else:
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ if not self.is_resource(path):
+ raise exceptions.NotResource("No such %s resource!" % path)
+
+ res = self.open_resource(path,"r")
+ # read the resource with persistentmodule
+ try:
+ obj = self.persistentmodule.loads(res.read())
+ #obj.set_path(path)
+ res.close()
+ return obj
+ except exceptions.ParseError,e:
+ logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
+ # returning an empty config in case of xml parsing failure.
+ return api.Configuration(path)
+
+ def close(self):
+ """ No operation in web storage close """
+ pass
+
+
+class WebResource(api.Resource):
+ def __init__(self,storage,path,mode,handle):
+ api.Resource.__init__(self,storage,path,mode)
+ self.handle = handle
+
+ def read(self,bytes=0):
+ if bytes == 0:
+ return self.handle.read()
+ else:
+ return self.handle.read(bytes)
+
+ def write(self,string):
+ if self.get_mode() == api.Storage.MODE_READ:
+ raise exceptions.StorageException("Writing attempted to %s in read-only mode." % self.path)
+ else:
+ self.handle.write(string)
+
+ def truncate(self,size=0):
+ raise exceptions.NotSupportedException()
+
+ def flush(self):
+ self.storage.flush_resource(self)
+
+ def close(self):
+ self.storage.close_resource(self)
+ self.handle.close()
+
+ def get_size(self):
+ if self.get_mode() == api.Storage.MODE_WRITE:
+ raise exceptions.StorageException("Reading resource size attempted to %s in write-only mode." % self.path)
+ return len(self.handle.getvalue())
+
+ def getvalue(self):
+ return self.handle.getvalue()
+
+
+class CarbonExtapi(object):
+ ACTIONS = { 'open_resource' : 'get_resource',
+ 'list_resources' : 'list_resources',
+ 'is_resource' : 'has_resource',
+ 'put_resource' : 'put_resource',
+ 'update_resource' : 'update_resource' }
+
+ """
+ A general container for Carbon extapi action
+ """
+ def __init__(self, path, **kwargs):
+ self.path = path
+ self.server_path = ''
+ self.service_path = ''
+ if path.startswith('http://'):
+ path = path.replace('http://','',1)
+ pathelems = path.split('/',1)
+ self.server_path = pathelems[0]
+ if len(pathelems) > 1:
+ self.service_path = pathelems[1]
+ self._username = kwargs.get('username', None)
+ self._password = kwargs.get('password', None)
+ authhandler = authenticate.CarbonAuthHandler()
+ authhandler.add_password(self.username, self.password)
+ self.conn = urllib2.build_opener(urllib2.HTTPCookieProcessor, authhandler, urllib2.ProxyHandler({}))
+
+ @property
+ def username(self):
+ if self._username == None:
+ self._username = getpass.getuser()
+ return self._username
+
+ @property
+ def password(self):
+ if self._password == None:
+ self._password = getpass.getpass()
+ return self._password
+
+ def checklogin(self):
+ """
+ Checks that we are logged in by loading the main page.
+ If we are not logged in it will redirect us to login page.
+ """
+ loginurl = "http://%(host)s/" % dict(host=self.server_path)
+ loginreq = urllib2.Request(loginurl)
+ print 'Checking login by opening URL %s ...' % loginurl
+ try:
+ resp = self.conn.open(loginreq)
+ except urllib2.URLError, e:
+ print str(e)
+ return False
+ return True
+
+ def _get_stringio_from_path(self,path):
+ """
+ return a StringIO object containing the data under a given path.
+ @return: StringIO buffer
+ @raise exception.NotResource: if the resource under path is not found
+ """
+ path = utils.resourceref.remove_begin_slash(path)
+ action_url = self._get_action_url('open_resource', path)
+ req = urllib2.Request(action_url)
+ try:
+ resp = self.conn.open(req)
+ bytes = resp.read()
+ strio = StringIO.StringIO(bytes)
+ return strio
+ except urllib2.HTTPError,e:
+ raise exceptions.NotResource("The given path %s could not be retrived from this storage. Server returned status %s." % (path, e))
+
+ def _get_action_url(self, action, path, **kwargs):
+ path = utils.resourceref.remove_begin_slash(path)
+ return "%s/%s/%s" % (self.path,self.ACTIONS[action], urllib.quote(path))
+
+ def list_resources_for_type(self,path,type, recurse=False):
+ """
+ find the resources under certain path/path
+ @param path : reference to path where resources are searched
+ @param type : resources for particular carbon specific type.
+ @param recurse : defines whether to return resources directly under the path or does the listing recurse to subfolders.
+ Default value is False. Set to True to enable recursion.
+ """
+ try:
+ path = utils.resourceref.join_refs([path,'.'+type])
+ path = utils.resourceref.remove_begin_slash(path)
+ query = self._get_action_url('list_resources', path)
+ req = urllib2.Request(query)
+ resp = self.conn.open(req)
+ if resp.code == httplib.OK:
+ bytes = resp.read()
+ reader = persistentjson.ResourceListReader()
+ reslist = reader.loads(bytes)
+ return reslist
+ else:
+ return []
+ except exceptions.NotFound:
+ return []
+
+ def list_resources(self,path, recurse=False):
+ """
+ find the resources under certain path/path
+ @param path : reference to path where resources are searched
+ @param recurse : defines whether to return resources directly under the path or does the listing recurse to subfolders.
+ Default value is False. Set to True to enable recursion.
+ """
+ try:
+ path = utils.resourceref.remove_begin_slash(path)
+ query = self._get_action_url('list_resources', path)
+ req = urllib2.Request(query)
+ resp = self.conn.open(req)
+ if resp.code == httplib.OK:
+ bytes = resp.read()
+ reslist = simplejson.loads(bytes)
+ return reslist.get('resources',[])
+ else:
+ return []
+ except exceptions.NotFound:
+ return []
+
+
+ def update_resource(self, path, data):
+ """
+ Update a resource to carbon. The resource can be a CarbonConfiguration or FeatureList object.
+ @param object: The object which is dumped to dict with persistentjson and then updated to server.
+ """
+ try:
+ path = utils.resourceref.remove_begin_slash(path)
+ query = self._get_action_url('update_resource', path)
+ jsondata = simplejson.dumps(data)
+ encdata = urllib.urlencode({'data' : jsondata})
+ req = urllib2.Request(query, encdata)
+
+ resp = self.conn.open(req)
+ if resp.code == httplib.OK:
+ bytes = resp.read()
+ respdata = simplejson.loads(bytes)
+ success = respdata.get('success') == True
+ if success:
+ logging.getLogger('cone').info('Carbon update succeeds to path %s.' % (respdata.get('path')))
+ else:
+ logging.getLogger('cone').error('Carbon update %s failed %s' % (path,respdata.get('errors')))
+ return success
+ else:
+ logging.getLogger('cone').error('Carbon update %s failed %s: %s' % (path,resp.code, resp))
+ return False
+ except urllib2.HTTPError,e:
+ utils.log_exception(logging.getLogger('cone'), "HTTPError in %s, %s" % (query,e))
+ return False
+
+ def create_feature(self,path, feature, parent=None):
+ """
+ Create new Carbon feature based on Feature object.
+ @param path: The path to the featurelist where the feature is created.
+ @param feature: The feature object
+ @param parent: A possible parent feature ref
+ """
+ try:
+ path = utils.resourceref.remove_begin_slash(path)
+ query = self._get_action_url('put_resource', path)
+ data = persistentjson.dumps(feature)
+ if parent:
+ data['parent'] = parent
+ jsondata = simplejson.dumps(data)
+ encdata = urllib.urlencode({'data' : jsondata})
+ req = urllib2.Request(query, encdata)
+
+ resp = self.conn.open(req)
+ if resp.code == httplib.OK:
+ bytes = resp.read()
+ respdata = simplejson.loads(bytes)
+ success = respdata.get('success') == True
+ if success:
+ logging.getLogger('cone').info('New Carbon feature created to path %s.' % (respdata.get('path')))
+ else:
+ logging.getLogger('cone').error('Feature %s creation failed %s' % (feature.fqr,respdata.get('errors')))
+ return success
+ else:
+ logging.getLogger('cone').error('Feature %s creation failed %s: %s' % (feature.fqr,resp.code, resp))
+ return False
+ except urllib2.HTTPError,e:
+ utils.log_exception(logging.getLogger('cone'), "HTTPError in %s, %s" % (query,e))
+ return False
+
+ def create_featurelist(self, path, featurelist):
+ """
+ Create new Carbon featurelist to carbon.
+ @param featurelist: The FeatureList object which is created.
+ @return: tuple (success, created_path) where success indicates the success of the operation
+ and created_path is the newly created featurelist path on success.
+ """
+ try:
+ path = utils.resourceref.remove_begin_slash(path)
+ query = self._get_action_url('put_resource', path)
+ data = persistentjson.FeatureListCreateWriter().dumps(featurelist)
+ jsondata = simplejson.dumps(data)
+ encdata = urllib.urlencode({'data' : jsondata})
+ req = urllib2.Request(query, encdata)
+
+ resp = self.conn.open(req)
+ if resp.code == httplib.OK:
+ bytes = resp.read()
+ respdata = simplejson.loads(bytes)
+ success = respdata.get('success') == True
+ newpath = respdata.get('path')
+ if success:
+ logging.getLogger('cone').info('New Carbon featurelist created to path %s.' % (newpath))
+ else:
+ logging.getLogger('cone').error('FeatureList %s creation failed %s' % (featurelist.path,respdata.get('errors')))
+ return (success, newpath)
+ else:
+ logging.getLogger('cone').error('FeatureList %s creation failed %s: %s' % (featurelist.path,resp.code, resp))
+ return (False,'')
+ except urllib2.HTTPError,e:
+ utils.log_exception(logging.getLogger('cone'), "HTTPError in %s, %s" % (query,e))
+ return (False,'')
+
+ def create_configuration(self, path, configuration):
+ """
+ Create new Carbon configuration to carbon.
+ @param path: The path to the configuration
+ @param configuration: The CarbonConfiguration object
+ @return: tuple (success, created_path) where success indicates the success of the operation
+ and created_path is the newly created configuration path on success.
+ """
+ try:
+ path = utils.resourceref.remove_begin_slash(path)
+ query = self._get_action_url('put_resource', path)
+ data = persistentjson.ConfigurationCreateWriter().dumps(configuration)
+ jsondata = simplejson.dumps(data)
+ encdata = urllib.urlencode({'data' : jsondata})
+ req = urllib2.Request(query, encdata)
+
+ resp = self.conn.open(req)
+ if resp.code == httplib.OK:
+ bytes = resp.read()
+ respdata = simplejson.loads(bytes)
+ success = respdata.get('success') == True
+ newpath = respdata.get('path')
+ if success:
+ logging.getLogger('cone').info('New Carbon configuration created to path %s.' % (newpath))
+ else:
+ logging.getLogger('cone').error('CarbonConfiguration %s creation failed %s' % (configuration.path,respdata.get('errors')))
+ return (success, newpath)
+ else:
+ logging.getLogger('cone').error('CarbonConfiguration %s creation failed %s: %s' % (configuration.path,resp.code, resp))
+ return (False,'')
+ except urllib2.HTTPError,e:
+ utils.log_exception(logging.getLogger('cone'), "HTTPError in %s, %s" % (query,e))
+ return (False,'')
+
+class ResourceCache(object):
+ """
+ Resource cache maintains a list of ConE resource names and their actual links to Carbon resources.
+ """
+ def __init__(self):
+ self._cache = {}
+
+ def add_configuration(self, configuration):
+ """
+ Add a list of Carbon configurations.
+ """
+
+ # Create the configuration as a layer and configuration root
+ self._cache[configuration.get_path()] = configuration.path
+ rootconf_path = configuration.name+'.confml'
+ rootconf = model.CarbonConfiguration(rootconf_path)
+ rootconf.include_configuration(configuration.get_path())
+ self._cache[rootconf_path] = rootconf
+
+ def add_featurelist(self, featurelist):
+ """
+ Add a list of Carbon configurations.
+ """
+ # Add the feature list under feature list folder
+ self._cache["featurelists/"+featurelist.get_path()] = featurelist.get_carbon_path()
+ pass
+
+ def add_resource(self, resourcepath):
+ """
+ Add a resource
+ """
+ confmlpath = persistentjson.CarbonResourceMapper().map_carbon_resource(resourcepath)
+ self._cache[confmlpath] = resourcepath
+
+ def list_resources(self, path, recurse=False):
+ """
+ List ConE resources under certain path
+ """
+ resources = []
+ path = utils.resourceref.insert_begin_slash(path)
+ for res in self._cache.keys():
+ (respath,resname) = posixpath.split(res)
+ respath = utils.resourceref.insert_begin_slash(respath)
+ if recurse:
+ if posixpath.normpath(respath).startswith(posixpath.normpath(path)):
+ resources.append(res)
+ else:
+ if posixpath.normpath(respath) == posixpath.normpath(path):
+ resources.append(res)
+ return resources
+
+ def is_resource(self,path):
+ return self._cache.has_key(path)
+
+ def get_resource_link(self,path):
+ """
+ Get a the actual Carbon resource link if it is found from cached storage.
+ """
+ linkpath = self._cache.get(path, None)
+ if isinstance(linkpath, str):
+ return linkpath
+ else:
+ return None
+
+ def get_mapped_resource(self, path):
+ # Try to make a carbon like resource path for a confml resource
+ if path.startswith('featurelists'):
+ object_type = 'featurelist'
+ elif path.endswith('/root.confml'):
+ object_type = 'configurationlayer'
+ else:
+ object_type = 'configurationroot'
+ carbonpath = persistentjson.CarbonResourceMapper().map_confml_resource(object_type, path)
+ return carbonpath
+
+ def add_resource_link(self,link, path):
+ """
+ Add a actual Carbon resource link. The link is the key which returns path when asked from get_resource_link.
+ @param link: is linking path to the actual carbon resource path
+ @param path: is the actual carbon path
+ """
+ self._cache[link] = path
+
+ def get_resource_object(self,path):
+ """
+ Get a the actual cached Carbon object if it is found.
+ """
+ cachebj = self._cache.get(path, None)
+ if isinstance(cachebj, model.CarbonConfiguration):
+ return cachebj
+ return None
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/zipstorage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/zipstorage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,377 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import zipfile,zlib, StringIO, os, logging
+import datetime
+import tempfile
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+from cone.public import api, utils, persistence, exceptions
+from cone.public.api import Resource, Storage, Configuration, Folder
+from cone.storage import metadata, common
+from cone.confml import persistentconfml
+
+
+class ZipException(exceptions.StorageException):
+ def __init__(self,value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+
+class ZipStorage(common.StorageBase):
+ """
+ A storage for zip file
+ """
+ TEMP_FILE = '_temp_%i.zip' % os.getpid()
+ def __init__(self, path ,mode, **kwargs):
+ """
+ Open the given filename object as a cpf zipfile
+ """
+ self.mode = mode
+ self.persistentmodule = persistentconfml
+ self.compression = zipfile.ZIP_DEFLATED
+ self.modified = False
+ self.logger = logging.getLogger('cone')
+ self.logger.debug("ZipStorage path %s open in mode %s" % (path,self.mode))
+ try:
+ # If opening the file in read/append mode check that the given file is a zipfile
+ if self.get_mode(mode) != self.MODE_WRITE:
+ if os.path.exists(path) and not zipfile.is_zipfile(path):
+ raise ZipException("The file %s is not a zip file!" % path)
+ self.zipfile = zipfile.ZipFile(path,self.mode,self.compression)
+ except IOError,e:
+ raise ZipException("ZipFile open error: %s" % e)
+ super(ZipStorage, self).__init__(path)
+
+ def _zippath(self, path):
+ """
+ Convert a norm path to zipfile path
+ """
+ normpath = utils.resourceref.norm(path)
+ return normpath.lstrip('.')
+
+ @classmethod
+ def supported_storage(cls,path):
+ """
+ Class method for determing if the given clas supports a storage by given path.
+ E.g. foo.zip, foo.cpd, foo/bar, http://foo.com/
+ @param path:
+ @return: Boolean value. True if the storage of the path is supported. False if not.
+ """
+ if utils.resourceref.get_ext(path) == "zip" or \
+ utils.resourceref.get_ext(path) == "cpf":
+ return True
+ else:
+ return False
+
+ def open_resource(self,path,mode="r"):
+ strio = None
+ path = utils.resourceref.remove_begin_slash(path)
+ fullpath = utils.resourceref.join_refs([self.get_current_path(),path])
+ try:
+ if self.get_mode(mode) == self.MODE_READ:
+ if not self.is_resource(fullpath):
+ raise exceptions.NotResource("Resource is not found %s" % fullpath)
+ bytes = self.zipfile.read(fullpath)
+ strio = StringIO.StringIO(bytes)
+ elif self.get_mode(mode) == self.MODE_APPEND:
+ if not self.is_resource(fullpath):
+ raise exceptions.NotResource("Resource is not found %s" % fullpath)
+ bytes = self.zipfile.read(fullpath)
+ # delete the "old" resource
+ self.delete_resource(fullpath)
+ strio = StringIO.StringIO(bytes)
+ strio.seek(0, os.SEEK_END)
+
+ elif self.get_mode(mode) == self.MODE_WRITE:
+ if self.is_resource(fullpath):
+ # delete the "old" resource
+ self.delete_resource(fullpath)
+ # Create a new string buffer because the resource is overwritten
+ strio = StringIO.StringIO()
+ else:
+ raise ZipException("Unrecognized mode %s" % mode)
+ res = ZipFileResource(self,fullpath,mode,strio)
+ self.__opened__(res)
+ return res
+ except KeyError:
+ raise exceptions.NotResource(path)
+
+ def is_resource(self,path):
+ path = utils.resourceref.remove_begin_slash(path)
+ files = self.zipfile.namelist()
+ try:
+ i = files.index(path)
+ return True
+ except ValueError:
+ return False
+
+ def is_dir(self,path):
+ """
+ Get an array of files in a folder
+ """
+ try:
+ zinfo = self.zipfile.getinfo(utils.resourceref.add_end_slash(path))
+ return True
+ except KeyError:
+ return False
+
+ def list_resources(self,path,recurse=False, empty_folders=False):
+ """
+ Get an array of files in a folder
+ """
+ path = utils.resourceref.remove_begin_slash(path)
+ fullpath = utils.resourceref.join_refs([self.get_current_path(),path])
+ fullpath = self._zippath(fullpath)
+ retarray = []
+ filelist = self.zipfile.namelist()
+ for name in filelist:
+ (filepath,filename) = os.path.split(name)
+ curname = utils.resourceref.replace_dir(name, self.get_current_path(),'')
+ # return directories only if specified
+ if empty_folders == True or not self.is_dir(name):
+ # Skip the filename if it is marked as deleted
+ if self.__has_open__(name) and self.__get_open__(name)[-1].get_mode() == api.Storage.MODE_DELETE:
+ continue
+ if filepath == fullpath:
+ retarray.append(curname)
+ elif recurse and filepath.startswith(fullpath):
+ retarray.append(curname)
+ #retarray = sorted(utils.distinct_array(retarray))
+ return retarray
+
+ def import_resources(self,paths,storage,empty_folders=False):
+ for path in paths:
+ if not storage.is_resource(path) and empty_folders==False:
+ logging.getLogger('cone').warning("The given path is not a Resource in the storage %s! Ignoring from export!" % path)
+ continue
+ if storage.is_resource(path):
+ wres = self.open_resource(path,'wb')
+ res = storage.open_resource(path,"rb")
+ wres.write(res.read())
+ wres.close()
+ res.close()
+
+ elif storage.is_folder(path) and empty_folders:
+ self.create_folder(path)
+
+ def export_resources(self,paths,storage,empty_folders=False):
+
+ for path in paths:
+ if not self.is_resource(path) and empty_folders==False:
+ logging.getLogger('cone').warning("The given path is not a Resource in this storage %s! Ignoring from export!" % path)
+ continue
+ if self.is_resource(path):
+ wres = storage.open_resource(path,'wb')
+ res = self.open_resource(path,"rb")
+ wres.write(res.read())
+ wres.close()
+ res.close()
+
+ if self.is_folder(path) and empty_folders:
+ storage.create_folder(path)
+
+
+ def close_resource(self, res):
+ """
+ Close the given resource instance. Normally this is called by the Resource object
+ in its own close.
+ @param res: the resource object to close.
+ """
+ try:
+ self.__closed__(res)
+ if self.get_mode(self.mode) != api.Storage.MODE_READ and \
+ (res.get_mode() == api.Storage.MODE_WRITE or res.get_mode() == api.Storage.MODE_APPEND):
+ self.zipfile.writestr(res.path,res.getvalue())
+ except KeyError,e:
+ raise exceptions.StorageException("No such %s open resource! %s" % (res.path,e))
+
+
+ def save_resource(self, res):
+ """
+ Flush the changes of a given resource instance. Normally this is called by the Resource object
+ in its own save.
+ @param res: the resource to the resource to save.
+ """
+ if not self.__has_resource__(res):
+ raise exceptions.NotResource("No such %s open resource!" % res.path)
+ else:
+ self.zipfile.writestr(res.path,res.getvalue())
+
+ def delete_resource(self,path):
+ """
+ Delete the given resource from storage
+ @param res : Resource object to the resource
+ raises a NotSupportedException exception if delete operation is not supported by the storage
+ """
+ # First close all open resources
+ for res in self.__get_open__(path):
+ self.__closed__(res)
+ self.modified = True
+ self.zipfile.filelist.remove(self.zipfile.NameToInfo[path])
+ del self.zipfile.NameToInfo[path]
+
+
+ def create_folder(self,path):
+ """
+ Create a folder entry to a path
+ @param path : path to the folder
+ """
+ fullpath = utils.resourceref.join_refs([self.get_current_path(),path])
+ fullpath = utils.resourceref.add_end_slash(self._zippath(fullpath))
+ if self.is_folder(fullpath):
+ # delete the "old" resource
+ self.delete_resource(fullpath)
+ now = datetime.datetime.now()
+ zinfo = zipfile.ZipInfo(fullpath,
+ (now.year,now.month, now.day,
+ now.hour, now.minute, now.second)
+ )
+ # set an external attribute for directory entry
+ zinfo.external_attr = 0x10
+ zinfo.extract_version = 10
+ self.zipfile.writestr(zinfo,'')
+
+ def delete_folder(self,path):
+ """
+ Delete a folder entry from a path. The path must be empty.
+ @param path : path to the folder
+ """
+ pass
+
+ def is_folder(self,path):
+ """
+ Check if the given path is an existing folder in the storage
+ @param path : path to the folder
+ """
+ fullpath = utils.resourceref.join_refs([self.get_current_path(),path])
+ folderpath = self._zippath(fullpath)
+ return self.is_dir(folderpath)
+
+ def close(self):
+ if self.zipfile:
+ super(ZipStorage,self).close()
+ self.zipfile.close()
+ # Recreate the zip file if the zip has been modified to make a zip without
+ # duplicate local file entries
+ if self.modified:
+ oldfile = None
+ newzipfile = None
+ tmp_path = os.path.join(tempfile.gettempdir(), self.TEMP_FILE)
+ os.rename(self.path, tmp_path)
+ oldfile = zipfile.ZipFile(tmp_path,"r")
+ newzipfile = zipfile.ZipFile(self.path,"w",self.compression)
+ for fileinfo in oldfile.infolist():
+ newzipfile.writestr(fileinfo, oldfile.read(fileinfo.filename))
+ if oldfile: oldfile.close()
+ if newzipfile: newzipfile.close()
+ os.unlink(tmp_path)
+ self.zipfile = None
+ else:
+ raise exceptions.StorageException('Storage %s has been already closed!' % self.path)
+
+ def unload(self, path, object):
+ """
+ Dump a given object to the storage (reference is fetched from the object)
+ @param object: The object to dump to the storage, which is expected to be an instance
+ of Base class.
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ if not isinstance(object, api.Configuration):
+ raise exceptions.StorageException("Cannot dump object type %s" % object.__class__)
+ if self.get_mode(self.mode) != api.Storage.MODE_READ:
+ res = self.open_resource(path,"wb")
+ data = "%s" % self.persistentmodule.dumps(object)
+ res.write(data)
+ res.close()
+ return
+
+ def load(self, path):
+ """
+ Load an from a reference.
+ """
+ # Add the current path in front of the given path
+ path = utils.resourceref.join_refs([self.get_current_path(), path])
+ if not utils.resourceref.get_ext(path) == "confml":
+ raise exceptions.StorageException("Cannot load reference type %s" % utils.resourceref.get_ext(path))
+ if self.is_resource(path):
+ res = self.open_resource(path,"r")
+ # read the resource with persistentmodule
+ try:
+ obj = self.persistentmodule.loads(res.read())
+ obj.set_path(path)
+ res.close()
+ return obj
+ except exceptions.ParseError,e:
+ logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
+ # returning an empty config in case of xml parsing failure.
+ return api.Configuration(path)
+ else:
+ raise exceptions.NotResource("No such %s resource!" % path)
+
+
+class ZipFileResource(Resource):
+ def __init__(self,storage,path,mode,handle):
+ Resource.__init__(self,storage,path,mode)
+ self.handle = handle
+
+ def read(self,bytes=0):
+ if bytes == 0:
+ return self.handle.read()
+ else:
+ return self.handle.read(bytes)
+
+ def write(self,string):
+ if self.get_mode() == api.Storage.MODE_READ:
+ raise exceptions.StorageException("Writing attempted to %s in read-only mode." % self.path)
+ else:
+ self.handle.write(string)
+
+ def truncate(self,size=0):
+ raise exceptions.NotSupportedException()
+
+ def save(self):
+ self.storage.save_resource(self)
+
+ def close(self):
+ self.storage.close_resource(self)
+ self.handle.close()
+
+ def get_size(self):
+ if self.get_mode() == api.Storage.MODE_WRITE:
+ raise exceptions.StorageException("Reading resource size attempted to %s in write-only mode." % self.path)
+ return len(self.handle.getvalue())
+
+ def getvalue(self):
+ return self.handle.getvalue()
+
+ def get_content_info(self):
+ if self.content_info == None:
+ self.content_info = utils.make_content_info(self, self.handle.getvalue())
+
+ return self.content_info
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/test.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/test.xml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/tests/cone_input.zip
Binary file configurationengine/source/cone/tests/cone_input.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import os,sys,unittest
+from optparse import OptionParser, OptionGroup
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(0, os.path.join(ROOT_PATH,'..'))
+sys.path.insert(0, os.path.join(ROOT_PATH,'../..'))
+sys.path.insert(0, os.path.join(ROOT_PATH,'../../testautomation'))
+
+import cone.storage.tests
+import cone.core.tests
+import cone.confml.tests
+import cone.carbon.tests
+import cone.public.tests
+from testautomation import testcli
+
+def collect_suite():
+ suite = unittest.TestSuite()
+ suite.addTests(cone.storage.tests.collect_suite())
+ suite.addTests(cone.core.tests.collect_suite())
+ suite.addTests(cone.confml.tests.collect_suite())
+ suite.addTests(cone.carbon.tests.collect_suite())
+ suite.addTests(cone.public.tests.collect_suite())
+ return suite
+
+if __name__ == '__main__':
+ testcli.run(collect_suite())
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/dev-tools/find_tabs.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/dev-tools/find_tabs.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+
+def main(start):
+ for root, dirs, files in os.walk(start):
+ for fn in files:
+ if not fn.endswith('.py'):
+ continue
+ full_name = os.path.join(root, fn)
+ f = open(full_name)
+ for index, line in enumerate(f.readlines()):
+ if '\t' in line:
+ print '%s:%s: %s' % (full_name, index, line.rstrip())
+ f.close()
+
+if __name__ == '__main__':
+ import sys
+ if len(sys.argv):
+ main(sys.argv[1])
+ else:
+ main('.')
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/ez_setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/ez_setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,291 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#!python
+"""Bootstrap setuptools installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+ from ez_setup import use_setuptools
+ use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import sys
+DEFAULT_VERSION = "0.6c9"
+DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+
+md5_data = {
+ 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
+ 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
+ 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
+ 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
+ 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
+ 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
+ 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
+ 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
+ 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
+ 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+ 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
+ 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
+ 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
+ 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
+ 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
+ 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
+ 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
+ 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
+ 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
+ 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
+ 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
+ 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
+ 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
+ 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
+ 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
+ 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
+ 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
+ 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
+ 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
+ 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
+ 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
+ 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
+ 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
+ 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
+}
+
+import sys, os
+try: from hashlib import md5
+except ImportError: from md5 import md5
+
+def _validate_md5(egg_name, data):
+ if egg_name in md5_data:
+ digest = md5(data).hexdigest()
+ if digest != md5_data[egg_name]:
+ print >>sys.stderr, (
+ "md5 validation of %s failed! (Possible download problem?)"
+ % egg_name
+ )
+ sys.exit(2)
+ return data
+
+def use_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ download_delay=15
+):
+ """Automatically find/download setuptools and make it available on sys.path
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end with
+ a '/'). `to_dir` is the directory where setuptools will be downloaded, if
+ it is not already available. If `download_delay` is specified, it should
+ be the number of seconds that will be paused before initiating a download,
+ should one be required. If an older version of setuptools is installed,
+ this routine will print a message to ``sys.stderr`` and raise SystemExit in
+ an attempt to abort the calling script.
+ """
+ was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
+ def do_download():
+ egg = download_setuptools(version, download_base, to_dir, download_delay)
+ sys.path.insert(0, egg)
+ import setuptools; setuptools.bootstrap_install_from = egg
+ try:
+ import pkg_resources
+ except ImportError:
+ return do_download()
+ try:
+ pkg_resources.require("setuptools>="+version); return
+ except pkg_resources.VersionConflict, e:
+ if was_imported:
+ print >>sys.stderr, (
+ "The required version of setuptools (>=%s) is not available, and\n"
+ "can't be installed while this script is running. Please install\n"
+ " a more recent version first, using 'easy_install -U setuptools'."
+ "\n\n(Currently using %r)"
+ ) % (version, e.args[0])
+ sys.exit(2)
+ else:
+ del pkg_resources, sys.modules['pkg_resources'] # reload ok
+ return do_download()
+ except pkg_resources.DistributionNotFound:
+ return do_download()
+
+def download_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ delay = 15
+):
+ """Download setuptools from a specified location and return its filename
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end
+ with a '/'). `to_dir` is the directory where the egg will be downloaded.
+ `delay` is the number of seconds to pause before an actual download attempt.
+ """
+ import urllib2, shutil
+ egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
+ url = download_base + egg_name
+ saveto = os.path.join(to_dir, egg_name)
+ src = dst = None
+ if not os.path.exists(saveto): # Avoid repeated downloads
+ try:
+ from distutils import log
+ if delay:
+ log.warn("""
+---------------------------------------------------------------------------
+This script requires setuptools version %s to run (even to display
+help). I will attempt to download it for you (from
+%s), but
+you may need to enable firewall access for this script first.
+I will start the download in %d seconds.
+
+(Note: if this machine does not have network access, please obtain the file
+
+ %s
+
+and place it in this directory before rerunning this script.)
+---------------------------------------------------------------------------""",
+ version, download_base, delay, url
+ ); from time import sleep; sleep(delay)
+ log.warn("Downloading %s", url)
+ src = urllib2.urlopen(url)
+ # Read/write all in one block, so we don't create a corrupt file
+ # if the download is interrupted.
+ data = _validate_md5(egg_name, src.read())
+ dst = open(saveto,"wb"); dst.write(data)
+ finally:
+ if src: src.close()
+ if dst: dst.close()
+ return os.path.realpath(saveto)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def main(argv, version=DEFAULT_VERSION):
+ """Install or upgrade setuptools and EasyInstall"""
+ try:
+ import setuptools
+ except ImportError:
+ egg = None
+ try:
+ egg = download_setuptools(version, delay=0)
+ sys.path.insert(0,egg)
+ from setuptools.command.easy_install import main
+ return main(list(argv)+[egg]) # we're done here
+ finally:
+ if egg and os.path.exists(egg):
+ os.unlink(egg)
+ else:
+ if setuptools.__version__ == '0.0.1':
+ print >>sys.stderr, (
+ "You have an obsolete version of setuptools installed. Please\n"
+ "remove it from your system entirely before rerunning this script."
+ )
+ sys.exit(2)
+
+ req = "setuptools>="+version
+ import pkg_resources
+ try:
+ pkg_resources.require(req)
+ except pkg_resources.VersionConflict:
+ try:
+ from setuptools.command.easy_install import main
+ except ImportError:
+ from easy_install import main
+ main(list(argv)+[download_setuptools(delay=0)])
+ sys.exit(0) # try to force an exit
+ else:
+ if argv:
+ from setuptools.command.easy_install import main
+ main(argv)
+ else:
+ print "Setuptools version",version,"or greater has been installed."
+ print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
+
+def update_md5(filenames):
+ """Update our built-in md5 registry"""
+
+ import re
+
+ for name in filenames:
+ base = os.path.basename(name)
+ f = open(name,'rb')
+ md5_data[base] = md5(f.read()).hexdigest()
+ f.close()
+
+ data = [" %r: %r,\n" % it for it in md5_data.items()]
+ data.sort()
+ repl = "".join(data)
+
+ import inspect
+ srcfile = inspect.getsourcefile(sys.modules[__name__])
+ f = open(srcfile, 'rb'); src = f.read(); f.close()
+
+ match = re.search("\nmd5_data = {\n([^}]+)}", src)
+ if not match:
+ print >>sys.stderr, "Internal error!"
+ sys.exit(2)
+
+ src = src[:match.start(1)] + repl + src[match.end(1):]
+ f = open(srcfile,'w')
+ f.write(src)
+ f.close()
+
+
+if __name__=='__main__':
+ if len(sys.argv)>2 and sys.argv[1]=='--md5update':
+ update_md5(sys.argv[2:])
+ else:
+ main(sys.argv[1:])
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/build_egg_info.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/build_egg_info.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+# Script for generating the egg-info directories for all needed plug-ins.
+#
+# This is needed, because running some of the tests from Eclipse or
+# command line requires the egg-info dirs to be present for the plug-ins
+# to be found.
+
+import sys, os, subprocess, shutil
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+DEBUG = False
+
+def generate_egg_info(path):
+ """Generate egg-info for the given plug-in path if possible and necessary."""
+ if not os.path.isdir(path) or "setup.py" not in os.listdir(path):
+ return
+
+ # Check if egg-info has already been generated
+ for name in os.listdir(path):
+ egg_info_path = os.path.join(path, name)
+ if os.path.isdir(egg_info_path) and name.endswith('.egg-info'):
+ # xxx.egg-info is present in the directory, check if it is old
+ setup_py_path = os.path.join(path, 'setup.py')
+ if os.stat(setup_py_path).st_mtime < os.stat(egg_info_path).st_mtime:
+ if DEBUG: print "No need to generate egg-info for '%s'" % path
+ return
+ else:
+ if DEBUG: print "egg-info for '%s' is out of date, removing old and generating new" % path
+ shutil.rmtree(egg_info_path)
+
+ # Run the egg-info generation command
+ orig_workdir = os.getcwd()
+ try:
+ if DEBUG: print "Generating egg-info for '%s'..." % path
+ os.chdir(path)
+ p = subprocess.Popen("python setup.py egg_info", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ if p.returncode != 0:
+ print >>sys.stderr, "Could not generate egg-info for '%s'!" % path
+ print >>sys.stderr, "Command stdout output:"
+ print >>sys.stderr, out
+ print >>sys.stderr, "Command stderr output:"
+ print >>sys.stderr, err
+ else:
+ if DEBUG:
+ print "Done"
+ print "Command output:"
+ print out
+ finally:
+ os.chdir(orig_workdir)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
+
+
+import pkg_resources
+import sys,os
+
+try:
+ pkg_resources.require("Cone")
+except pkg_resources.DistributionNotFound:
+ ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+ sys.path.append(ROOT_PATH)
+ sys.path.append(os.path.join(ROOT_PATH,'..'))
+ sys.path.append(os.path.join(ROOT_PATH,'../..'))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/commandml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/commandml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,539 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author
+'''
+ConE plugin to run external applications/tools with given parameters in .commandml file. Notice that values can be also
+fecthed from ConfML to maximize portability and minimize maintenance.
+'''
+
+import re
+import os
+import sys
+import logging
+import types
+
+import subprocess
+import __init__
+
+from cone.public import exceptions,plugin,utils,api, settings
+
+class CommandImpl(plugin.ImplBase):
+ """
+ Plugin implementation class.
+ """
+
+ IMPL_TYPE_ID = "commandml"
+
+
+ def __init__(self,ref,configuration, reader):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)###3
+ self.desc = ""
+ self.logger = logging.getLogger('cone.commandml(%s)' % self.ref)
+ self.reader = reader
+
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ """
+ self.create_output()
+ return
+
+ def generate_layers(self,layers):
+ """
+ Generate the given Configuration layers.
+ """
+ self.logger.info('Generating layers %s' % layers)
+ self.create_output(layers)
+ return
+
+ def create_output(self, layers=None):
+ """
+ Function to generate output files.
+ """
+
+ tmpDict = self.__create_helper_variables()
+
+ for element in self.reader.elements:
+ #Element can be either command or condition.
+ element.set_logger(self.logger)
+ element.execute(tmpDict)
+ return
+
+ def __create_helper_variables(self):
+ """
+ Internal function to create dictionary containing most often used ConE "environment" variables.
+ """
+ tmp = {}
+ tmp["%CONE_OUT%"] = self.output
+ tmp["%CONE_OUT_ABSOLUTE%"] = os.path.abspath(self.output)
+ return tmp
+
+ def has_ref(self, refs):
+ """
+ @returns True if the implementation uses the given ref as input value.
+ Otherwise return False.
+ """
+
+ # return true for now so that content copying is not filtered
+ return None
+
+class CommandImplReader(plugin.ReaderBase):
+ """
+ Parses a single commandml file
+ """
+ NAMESPACE = 'http://www.s60.com/xml/commandml/1'
+ FILE_EXTENSIONS = ['commandml']
+
+ def __init__(self):
+ """
+ Constructor
+ """
+ self.output_dir = None
+ self.input_dir = None
+ self.namespaces = [self.NAMESPACE]
+ self.dview = None
+ self.elements = []
+ self.tags = None
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = CommandImplReader()
+ reader.set_default_view(configuration.get_default_view())
+ reader.from_etree(etree)
+ impl = CommandImpl(resource_ref, configuration, reader)
+ if reader.tags:
+ impl.set_tags(reader.tags)
+ return impl
+
+ def set_default_view(self, dview):
+ """
+ Function to set default view that is needed when solving out ConfML reference information
+ """
+ self.dview = dview
+
+ def from_etree(self, etree):
+ """
+ Parser function for commandml element.
+ """
+ self.parse_tree(etree)
+
+ def parse_tree(self, etree):
+ """
+ General parse function for condition and command elements.
+ """
+ elements = list(etree)
+ for element in elements:
+ if element.tag == "{%s}condition" % self.namespaces[0]:
+ self.elements.append(self.parse_condition(element))
+ elif element.tag == "{%s}command" % self.namespaces[0]:
+ self.elements.append(self.parse_command(element))
+ else:
+ pass
+ self.tags = self.parse_tags(etree)
+
+ def parse_condition(self, etree):
+ """
+ Parse function for condition element.
+ """
+ condition = Condition()
+ condition.set_condition(etree.get("value"))
+ condition.set_commands(self.parse_commands(etree))
+ condition.set_default_view(self.dview)
+ return condition
+
+ def parse_commands(self,etree):
+ """
+ Parser function for commands.
+ """
+ commands = []
+ for com_elem in etree.findall("{%s}command" % self.namespaces[0]):
+ commands.append(self.parse_command(com_elem))
+ return commands
+
+ def parse_command(self,etree):
+ """
+ Parser function for single command.
+ """
+ cmd = Command()
+ cmd.set_executable(etree.get("executable"))
+ cmd.set_shell(etree.get("shell"))
+ cmd.set_bufsize(etree.get("bufsize"))
+ cmd.set_cwd(etree.get("cwd"))
+ cmd.set_all_envs(etree.get("env"))
+ cmd.set_all_arguments(self.parse_arguments(etree))
+ cmd.set_all_pipes(self.parse_pipes(etree))
+ cmd.set_filters(self.parse_filters(etree))
+ cmd.set_default_view(self.dview)
+ return cmd
+
+ def parse_arguments(self,etree):
+ """
+ Parser function for command's arguments.
+ """
+ arguments = []
+ for argument in etree.findall("{%s}argument" % self.namespaces[0]):
+ value = argument.get("value")
+ if value:
+ arguments.append(value)
+ return arguments
+
+ def parse_pipes(self,etree):
+ """
+ Parser function for command's pipes.
+ """
+ pipes = {}
+ for argument in etree.findall("{%s}pipe" % self.namespaces[0]):
+ name = argument.get("name")
+ value = argument.get("value")
+ if name:
+ pipes[name] = value
+ return pipes
+
+ def parse_filters(self,etree):
+ """
+ Parser function for command's filters.
+ """
+ filters = []
+ for argument in etree.findall("{%s}filter" % self.namespaces[0]):
+ f = Filter()
+ f.set_severity(argument.get("severity"))
+ f.set_condition(argument.get("condition"))
+ f.set_input(argument.get("input"))
+ f.set_formatter(argument.get("formatter"))
+ filters.append(f)
+ return filters
+
+ def parse_tags(self,etree):
+ tags = {}
+ for tag in etree.getiterator("{%s}tag" % self.namespaces[0]):
+ tagname = tag.get('name','')
+ tagvalue = tag.get('value')
+ values = tags.get(tagname,[])
+ values.append(tagvalue)
+ tags[tagname] = values
+ return tags
+
+
+class Condition(object):
+ """
+ Condition class is a simple wrapper class for commands so that commands are executed
+ only if condition is True. Otherwise class does nothing. Class has similar interface
+ than Command class so that they can be used similar way from plugin perspective.
+ """
+
+ def __init__(self):
+ self.condition = None
+ self.commands = []
+ self.logger = None
+ self.dview = None
+
+ def set_condition(self, condition):
+ self.condition = condition
+
+ def set_default_view(self, dview):
+ self.dview = dview
+
+ def set_commands(self, commands):
+ self.commands = commands
+
+ def set_logger(self, logger):
+ self.logger = logger
+ for cmd in self.commands:
+ cmd.set_logger(logger)
+
+ def add_command(self, command):
+ self.command.append(command)
+
+ def execute(self, replaceDict=None):
+ if self.__solve_condition(self.condition):
+ #Condition is true -> running command
+ for command in self.commands:
+ command.execute(replaceDict)
+ else:
+ self.logger.info("Ignoring %s because it is evaluated as False." % self.condition)
+
+ def __solve_condition(self, condition_str):
+ """
+ Internal function to handle condition
+ """
+ if condition_str != "":
+ #Expanding ConfML information
+ modstr = utils.expand_delimited_tokens(
+ condition_str,
+ lambda ref, index: repr(self.dview.get_feature(ref).get_value()))
+ return eval(modstr)
+ else:
+ #Empty condition is true always.
+ return True
+
+class Command(object):
+ """
+ Command is a class that executes actual commands. It provides ways to handle input, output and error
+ streams and to control execution parameters.
+ """
+
+ def __init__(self):
+ """
+ Constructor
+ """
+ self.executable = None
+ self.shell = False
+ self.bufsize = 0
+ self.cwd = None
+ self.envs = None
+ self.arguments = []
+ self.pipes = {}
+ self.streams = {}
+ self.filters = []
+ self.logger = None
+ self.dview = None
+
+ def set_executable(self, executable):
+ self.executable = executable
+
+ def set_shell(self, shell):
+ if shell and shell.lower() in ('true', 'yes', '1', 1, True):
+ self.shell = True
+ else:
+ self.shell = False
+
+ def set_bufsize(self, bufsize):
+ if bufsize:
+ self.bufsize = int(bufsize)
+
+ def set_cwd(self, cwd):
+ self.cwd = cwd
+
+ def set_all_envs(self, envs):
+ if envs:
+ self.envs = eval(envs)
+ def set_default_view(self, dview):
+ self.dview = dview
+
+ def set_env(self, name, value):
+ self.envs[name] = value
+
+ def set_all_arguments(self, args):
+ self.arguments = args
+
+ def get_arguments_string(self):
+ """
+ Function to return arguments as a string
+ """
+ arg_string = ""
+ for value in self.arguments:
+ arg_string += value
+ arg_string += " "
+ return arg_string
+
+ def get_pipe(self, name, mode='w'):
+ """
+ Function to return pipe based on the pipe name in requested mode.
+ """
+ if self.pipes.has_key(name) and isinstance(self.pipes[name], types.IntType):
+ #Subprocess pipe
+ return self.pipes[name]
+ elif self.pipes.has_key(name) and isinstance(self.pipes[name], types.StringType):
+ return file(self.pipes[name], mode)
+ else:
+ return None
+
+ def set_streams(self, stdin, stdout, stderr):
+ self.streams["stdin"] = stdin
+ self.streams["stdout"] = stdout
+ self.streams["stderr"] = stderr
+
+ def get_streams(self, name, mode="r"):
+ if self.streams.has_key(name) and self.streams[name]:
+ #OK for streams set with subprocess.PIPE
+ return self.streams[name]
+ else:
+ #For file objects
+ return self.get_pipe(name, mode)
+
+ def set_filters(self, filters):
+ self.filters = filters
+ for f in self.filters:
+ f.set_command(self)
+
+ def get_filters(self):
+ return self.filters
+
+ def set_argument(self, value):
+ self.arguments.append(value)
+
+ def set_all_pipes(self, pipes):
+ for pipe in pipes.keys():
+ self.set_pipe(pipe, pipes[pipe])
+
+ def set_pipe(self, name, value):
+ if value == "PIPE":
+ #Creating new stream for this.
+ self.pipes[name] = subprocess.PIPE
+ elif value == "STDOUT":
+ self.pipes[name] = subprocess.STDOUT
+ else:
+ #Setting filename
+ self.pipes[name] = value
+ #self.pipes[name] = file(value, 'w')
+
+ def handle_filters(self):
+ """
+ """
+ for filter in self.filters:
+ filter.report(self.logger)
+
+ def execute(self, replaceDict=None):
+ self.solve_refs()
+
+ exit_code = 0
+ try:
+ try:
+ if self.cwd is not None:
+ cwd = self.__replace_helper_variables(self.cwd, replaceDict)
+ else:
+ cwd = self.cwd
+ command_str = self.executable + " " + self.__replace_helper_variables(self.get_arguments_string(), replaceDict)
+ self.logger.info("Running command: \"%s\"" % command_str)
+ self.logger.info("with args: shell=%s envs=%s cwd=%s bufsize=%s stdin=%s stdout=%s stderr=%s" \
+ % (self.shell, self.envs, cwd, self.bufsize, \
+ self.get_pipe("stdin", 'r'),self.get_pipe("stdout"), self.get_pipe("stderr")))
+ pid = subprocess.Popen(command_str, shell=self.shell, env=self.envs, cwd=cwd,\
+ bufsize=self.bufsize, stdin = self.get_pipe("stdin", 'r'),\
+ stdout = self.get_pipe("stdout"), stderr = self.get_pipe("stderr"))
+ #Waiting for process to complete
+ retcode = pid.wait()
+ #Storing stream information for possible further processing.
+ self.set_streams(pid.stdin, pid.stdout, pid.stderr)
+
+ if retcode < 0:
+ self.logger.error("Child was terminated by signal %s" % (-retcode))
+ else:
+ self.logger.info("Child returned: %s" % retcode)
+ except OSError, e:
+ self.logger.error("Execution failed: %s", repr(e))
+ self.handle_filters()
+ except Exception,e:
+ utils.log_exception(self.logger, "Failed to execute command: %s" % e)
+
+ def set_logger(self, logger):
+ self.logger = logger
+
+ def __replace_helper_variables(self, inputstr, dictionary):
+ retstr = inputstr
+ for key in dictionary.keys():
+ retstr = retstr.replace(key, dictionary[key])
+ return retstr
+
+ def solve_refs(self):
+ """
+ Function to solve references just before generation.
+ """
+
+ self.executable = self.__solve_ref(self.executable)
+ self.shell = self.__solve_ref(self.shell)
+ self.bufsize = self.__solve_ref(self.bufsize)
+ self.cwd = self.__solve_ref(self.cwd)
+ for argument in self.arguments:
+ self.arguments[self.arguments.index(argument)] = self.__solve_ref(argument)
+ for pipe in self.pipes.keys():
+ self.pipes[pipe] = self.__solve_ref(self.pipes[pipe])
+
+ def __solve_ref(self, inputstr):
+ """
+ Internal function to solve whether input is ref or just normal input string.
+ For refs actual ConfML value is resolved and returned. Non-refs are returned
+ as such.
+ """
+ if inputstr and isinstance(inputstr, types.StringType):
+ return utils.expand_refs_by_default_view(inputstr, self.dview)
+ else:
+ return inputstr
+
+
+
+class Filter(object):
+ """
+ Filter class handles printing information to ConE log using filtering information.
+ Filtering severity, condition and the format of output can be configured in command ml.
+ """
+
+ def __init__(self):
+ self.severity = None
+ self.condition = None
+ self.input = None
+ self.command = None
+ self.formatter = None
+
+ def set_severity(self, severity):
+ self.severity = severity
+
+ def set_condition(self, condition):
+ self.condition = condition
+
+ def set_input(self, input):
+ self.input = input
+
+ def set_command(self, command):
+ self.command = command
+
+ def set_formatter(self, formatter):
+ self.formatter = formatter
+
+ def report(self, logger):
+ input_pipe = self.command.get_streams(self.input)
+ if isinstance(input_pipe, types.FileType):
+ #Subprocess.PIPE and file descriptors supported only.
+ data = input_pipe.read()
+ pattern = re.compile(self.condition)
+ for line in data.splitlines():
+ mo = pattern.match(line)
+ if mo:
+ lf = self.__get_logger_function(logger)
+ if self.formatter:
+ lf(self.formatter % mo.groupdict())
+ else:
+ lf(line)
+
+ def __get_logger_function(self, logger):
+ if self.severity == "info":
+ return logger.info
+ elif self.severity == "warning":
+ return logger.warning
+ elif self.severity == "debug":
+ return logger.debug
+ elif self.severity == "exception":
+ return logger.exception
+ elif self.severity == "error":
+ return logger.error
+ elif self.severity == "critical":
+ return logger.critical
+ else:
+ #Default
+ return logger.info
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/confml/basic_setting_types_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/confml/basic_setting_types_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+
+
+
+ Feature with basic setting types (ConfML v2.0)
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file1.commandml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file1.commandml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file2.commandml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file2.commandml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/family/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/family/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/family/product/root.confml
Binary file configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/family/product/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/family/root.confml
Binary file configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/family/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/product.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/product.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/makedir.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/makedir.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os
+dir = sys.argv[1]
+if not os.path.exists(dir):
+ os.makedirs(dir)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/print_hello.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/print_hello.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import os, sys
+
+print "Hello"
+print "Cmd line args: %r" % sys.argv[1:]
+print "Env: %r" % os.environ
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_commandml_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_commandml_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+
+import __init__
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+from testautomation.base_testcase import BaseTestCase
+from commandplugin import commandml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+temp_dir = os.path.join(ROOT_PATH, "temp")
+testdata = os.path.join(ROOT_PATH,'project')
+
+class TestCommandPlugin(BaseTestCase):
+ def test_example_parse_prj(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impls = plugin.get_impl_set(config,'\.commandml$')
+
+ def test_generate(self):
+ orig_workdir = os.getcwd()
+ os.chdir(ROOT_PATH)
+ try:
+ OUTPUT_DIR = os.path.join(ROOT_PATH, 'output')
+ self.remove_if_exists(OUTPUT_DIR)
+
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impls = plugin.get_impl_set(config,'file2\.commandml$')
+ impls.output = OUTPUT_DIR
+ impls.generate()
+
+ self.assert_file_content_equals('hello.log',
+ "Hello\r\n" +
+ "Cmd line args: ['-c', 'some_config.txt', '-d', 'some_dir', '-x']\r\n" +
+ "Env: {'MYVAR': '123'}\r\n")
+
+ self.assert_file_content_equals('exec_in_output_test.log',
+ os.path.normpath(OUTPUT_DIR) + '\r\n')
+
+ # Check that the log file of the command that should not be
+ # executed does not exist
+ self.assertFalse(os.path.exists("should_not_be_created.log"))
+ finally:
+ os.chdir(orig_workdir)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_parse_commandml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_parse_commandml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, re, subprocess
+
+import __init__
+from cone.public import api, plugin
+from cone.storage import filestorage
+from testautomation.base_testcase import BaseTestCase
+from commandplugin.commandml import Command, Condition
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'project')
+
+class TestParseCommandMl(BaseTestCase):
+ def _get_impl(self, ref):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impl_set = plugin.get_impl_set(config, re.escape(ref) + '$')
+ self.assertEquals(len(impl_set), 1)
+ return iter(impl_set).next()
+
+ def test_parse_file1(self):
+ impl = self._get_impl('file1.commandml')
+ self.assertEquals(len(impl.reader.elements), 2)
+
+ cmd = impl.reader.elements[0]
+ self.assertTrue(isinstance(cmd, Command))
+ self.assertEquals(cmd.executable, r'c:\program1\run.exe')
+ self.assertEquals(cmd.shell, False)
+ self.assertEquals(cmd.bufsize, 0)
+ self.assertEquals(cmd.cwd, r'c:\program1')
+ self.assertEquals(cmd.envs, {'MYVAR': '123'})
+ self.assertEquals(cmd.arguments, ['-c some_config.txt',
+ '-d some_dir',
+ '-x'])
+ self.assertEquals(cmd.pipes, {'stdin': subprocess.PIPE,
+ 'stdout': 'program1.log'})
+
+ cond = impl.reader.elements[1]
+ self.assertTrue(isinstance(cond, Condition))
+ self.assertEquals(cond.condition, 'False')
+ self.assertEquals(len(cond.commands), 1)
+ cmd = cond.commands[0]
+ self.assertTrue(isinstance(cmd, Command))
+ self.assertEquals(cmd.executable, r'c:\program2\abc.exe')
+ self.assertEquals(cmd.shell, True)
+ self.assertEquals(cmd.bufsize, 0)
+ self.assertEquals(cmd.arguments, ['-c some_config.txt'])
+ self.assertEquals(cmd.pipes, {})
+
+ self.assertEquals(impl.get_tags(), {})
+
+ def test_parse_file2(self):
+ impl = self._get_impl('file2.commandml')
+ self.assertEquals(len(impl.reader.elements), 4)
+
+ self.assertTrue(isinstance(impl.reader.elements[0], Condition))
+ self.assertTrue(isinstance(impl.reader.elements[1], Condition))
+ self.assertTrue(isinstance(impl.reader.elements[2], Command))
+ self.assertTrue(isinstance(impl.reader.elements[3], Command))
+
+ self.assertEquals(impl.get_tags(), {'target': ['footarget']})
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeCommandPlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from commandplugin import __version__
+
+setup(
+ name = "conecommandplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "commandplugin.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine Configuration Tool Command plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['commandml = commandplugin.commandml:CommandImplReader']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,258 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+A plugin implementation for content selection from ConfigurationLayers.
+'''
+
+
+import re
+import os
+import sys
+import logging
+import shutil
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api,container
+from contentplugin import contentmlparser
+
+class ContentImpl(plugin.ImplBase):
+ """
+ ContentImpl plugin finds all content resources from each layer and copies
+ them to the output correctly. It follows the Configuration project override
+ rules, so that the topmost layer files override files on the previous layers.
+ """
+
+ IMPL_TYPE_ID = 'content'
+
+ def __init__(self,ref,configuration):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.desc = ""
+ self.logger = logging.getLogger('cone.content(%s)' % self.ref)
+ self.errors = False
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ if not self.errors:
+ copylist = self.get_full_copy_list()
+ outputfiles = [entry[1] for entry in copylist]
+ return outputfiles
+ else:
+ return []
+
+ def get_refs(self):
+ refs = []
+ for output in self.outputs:
+ refs.extend(output.get_refs())
+ if refs:
+ return refs
+ else:
+ return None
+
+ def get_full_copy_list(self, print_info=False):
+ fullcopylist = []
+ for output in self.outputs:
+ for input in output.inputs:
+ copylist = []
+ if print_info:
+ self.logger.info('Content copy items from %s to %s' % (input.dir,os.path.join(self.output,output.dir)))
+
+ if input.__class__.__name__ == "ContentInput":
+ copylist = self.create_copy_list(content=self.configuration.layered_content(),
+ input=input.dir,
+ output=os.path.join(self.output,output.dir),
+ include_pattern=input.get_include_pattern(),
+ exclude_pattern=input.get_exclude_pattern(),
+ files=input.get_filelist(),
+ flatten=output.flatten,
+ output_file=output.file)
+ elif input.__class__.__name__ == "ExternalContentInput":
+ #Handling external inputs separately
+ if input.dir != None:
+ fulldir = os.path.abspath(os.path.join(self.configuration.get_project().get_storage().get_path(),input.dir))
+ else:
+ fulldir = self.configuration.get_project().get_storage().get_path()
+
+ data = container.DataContainer()
+ for root, dirs, files in os.walk(fulldir):
+ for f in files:
+ filepath = utils.resourceref.norm(os.path.join(root, f))
+ key = utils.resourceref.replace_dir(filepath,fulldir,"")
+ data.add_value(key,filepath)
+ #data.add_value(filepath,filepath)
+ copylist = self.create_copy_list(content=data,
+ input=input.dir,
+ output=os.path.join(self.output,output.dir),
+ include_pattern=input.get_include_pattern(),
+ exclude_pattern=input.get_exclude_pattern(),
+ files=input.get_filelist(),
+ flatten=output.flatten,
+ output_file=output.file,
+ external=True)
+ else:
+ logging.getLogger('cone.content').warning("Unknown input %s" % (input.__class__.__name__))
+
+ fullcopylist += copylist
+
+ return fullcopylist
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ """
+ self.logger.info('Generating')
+ self.create_output()
+ return
+
+ def create_output(self,layers=None):
+ """
+ Create the output directory from the content folder files
+ """
+ if not self.errors:
+ datacontainer = self.configuration.layered_content(layers)
+ #root = self.configuration.get_root()
+ copylist = self.get_full_copy_list(True)
+ for copy_item in copylist:
+ sourceref = copy_item[0]
+ targetfile = copy_item[1]
+ external = copy_item[2]
+
+ self.logger.info('Copy from %s to %s' % (sourceref,targetfile))
+ if not os.path.exists(os.path.dirname(targetfile)):
+ os.makedirs(os.path.dirname(targetfile))
+ if not external:
+ outfile = open(targetfile,"wb")
+ res = self.configuration.get_storage().open_resource(sourceref,"rb")
+ outfile.write(res.read())
+ else:
+ shutil.copyfile(sourceref,targetfile)
+ return
+ else:
+ self.logger.error('Plugin had errors! Bailing out!')
+
+
+ def create_copy_list(self, **kwargs):
+ """
+ Return a list copy list where each element is a (from,to) tuple
+ """
+ datacontainer = kwargs.get('content',None)
+ input_dir = kwargs.get('input','')
+ output_dir = kwargs.get('output','')
+ output_file = kwargs.get('output_file','')
+ include_filter= kwargs.get('include_pattern','')
+ exclude_filter= kwargs.get('exclude_pattern','')
+ files = kwargs.get('files',[])
+ flatten = kwargs.get('flatten',False)
+ external = kwargs.get('external',False)
+ copylist = []
+ contentfiles = datacontainer.list_keys()
+ """
+ First get only the files list from content files.
+ Then apply the possible filters.
+ """
+ if input_dir == None:
+ self.logger.warning("Input dir is none!")
+
+
+ if files != []:
+ for f in files:
+ if f in contentfiles:
+ pass
+ elif f not in contentfiles:
+ self.logger.info("File: %s not found in content" % f)
+
+
+ if files != []:
+ filesfunc = lambda x: x.lower() in [f.lower() for f in files]
+ contentfiles = filter(filesfunc, contentfiles)
+ if include_filter != "":
+ filter_regexp = include_filter
+ filter_regexp = filter_regexp.replace('.','\.')
+ filter_regexp = filter_regexp.replace('*','.*')
+ self.logger.info("filtering with include %s" % filter_regexp)
+ contentfiles = utils.resourceref.filter_resources(contentfiles,filter_regexp)
+ if exclude_filter != "":
+ filter_regexp = exclude_filter
+ filter_regexp = filter_regexp.replace('.','\.')
+ filter_regexp = filter_regexp.replace('*','.*')
+ self.logger.info("filtering with exclude %s" % filter_regexp)
+ contentfiles = utils.resourceref.neg_filter_resources(contentfiles,filter_regexp)
+ for outfile in contentfiles:
+ sourcefile = ""
+ targetfile = ""
+
+ if input_dir != None and outfile.startswith(input_dir):
+ sourcefile = datacontainer.get_value(outfile)
+ if flatten:
+ targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(outfile)])
+ targetfile = utils.resourceref.norm(targetfile)
+ else:
+ targetfile = utils.resourceref.replace_dir(outfile,input_dir,output_dir)
+ elif external:
+ #External inputs
+ sourcefile = utils.resourceref.norm(datacontainer.get_value(outfile))
+
+ if flatten:
+ targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(sourcefile)])
+ targetfile = utils.resourceref.norm(targetfile)
+ else:
+ fulldir = os.path.abspath(os.path.join(self.configuration.get_project().get_storage().get_path(),input_dir))
+ targetfile = utils.resourceref.replace_dir(sourcefile,fulldir,output_dir)
+
+ if output_file:
+ #Renaming output if defined
+ targetfile = targetfile.replace(os.path.basename(targetfile), output_file)
+
+ if sourcefile and targetfile:
+ copylist.append((sourcefile,targetfile, external))
+ return copylist
+
+class ContentImplReaderBase(object):
+ FILE_EXTENSIONS = ['content', 'contentml']
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ parser = cls.parser_class()
+
+ desc = parser.parse_desc(etree)
+ outputs = parser.parse_outputs(etree)
+ phase = parser.parse_phase(etree)
+ tags = parser.parse_tags(etree)
+
+ impl = ContentImpl(resource_ref, configuration)
+ impl.desc = desc
+ impl.outputs = outputs
+ if tags:
+ impl.set_tags(tags)
+ for output in impl.outputs:
+ output.set_configuration(configuration)
+ if phase != None:
+ impl.set_invocation_phase(phase)
+
+ return impl
+
+class ContentImplReader1(ContentImplReaderBase, plugin.ReaderBase):
+ NAMESPACE = 'http://www.s60.com/xml/content/1'
+ parser_class = contentmlparser.Content1Parser
+
+class ContentImplReader2(ContentImplReaderBase, plugin.ReaderBase):
+ NAMESPACE = 'http://www.s60.com/xml/content/2'
+ parser_class = contentmlparser.Content2Parser
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,452 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+'''
+A plugin implementation for content selection from ConfigurationLayers.
+'''
+
+
+import re
+import os
+import sys
+import logging
+import shutil
+import copy
+import xml.parsers.expat
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+
+class ContentOutput(object):
+ def __init__(self, **kwargs):
+ self._dir = kwargs.get('dir',None)
+ self._file = kwargs.get('file',None)
+ self.flatten = kwargs.get('flatten',False)
+ self.inputs = kwargs.get('inputs', [])
+ self.configuration = None
+
+ def set_configuration(self, configuration):
+ self.configuration = configuration
+ for input in self.inputs:
+ input.configuration = self.configuration
+
+ def get_configuration(self, configuration):
+ self.configuration = configuration
+
+ def path_convert(self, path):
+ (drive, tail) = os.path.splitdrive(path)
+ return tail.lstrip('\\/')
+
+ def get_dir(self):
+ if self.configuration and ConfmlRefs.is_confml_ref(self._dir):
+ parts = self._dir.split(ConfmlRefs.ref_separator)
+ for (index, part) in enumerate(parts):
+ if ConfmlRefs.is_confml_ref(part):
+ ref = ConfmlRefs.get_confml_ref(part)
+ parts[index] = self.configuration.get_default_view().get_feature(ref).value
+ parts[index] = self.path_convert(parts[index])
+ else:
+ parts[index] = part
+ return (os.sep).join(parts)
+ else:
+ return self.path_convert(self._dir)
+
+ def set_dir(self, dir):
+ self._dir = dir
+
+ def get_file(self):
+ if self.configuration and self._file != None and ConfmlRefs.is_confml_ref(self._file):
+ parts = self._file.split(ConfmlRefs.ref_separator)
+ for (index, part) in enumerate(parts):
+ if ConfmlRefs.is_confml_ref(part):
+ ref = ConfmlRefs.get_confml_ref(part)
+ parts[index] = self.configuration.get_default_view().get_feature(ref).value
+ parts[index] = self.path_convert(parts[index])
+ else:
+ parts[index] = part
+ return (os.sep).join(parts)
+ else:
+ return self._file
+
+ def set_file(self, file):
+ self._file = file
+
+ dir = property(get_dir, set_dir)
+ file = property(get_file, set_file)
+
+ def get_refs(self):
+ refs = []
+ for input in self.inputs:
+ refs.extend(input.get_refs())
+ return refs
+
+
+class ContentInput(object):
+ def __init__(self, **kwargs):
+ self._dir = kwargs.get('dir',None)
+ self._file = kwargs.get('file',None)
+ self._include = kwargs.get('include', {})
+ self._exclude = kwargs.get('exclude', {})
+ self.configuration = None
+
+ @property
+ def dir(self):
+
+ if self.configuration and ConfmlRefs.is_confml_ref(self._dir):
+ cref = ConfmlRefs.get_confml_ref(self._dir)
+ return self.configuration.get_default_view().get_feature(cref).value
+ else:
+ return self._dir
+
+ @property
+ def file(self):
+
+ if self._file and self.configuration and ConfmlRefs.is_confml_ref(self._file):
+ cref = ConfmlRefs.get_confml_ref(self._file)
+ return self.configuration.get_default_view().get_feature(cref).value
+ else:
+ return self._file
+
+
+ def _dereference_dict(self, data):
+ if self.configuration:
+ # Make a deep copy of the data, or otherwise get_refs() will
+ # return the correct refs only on the first call, as the
+ # references are replaced here
+ data = copy.deepcopy(data)
+
+ dview = self.configuration.get_default_view()
+ for key in data:
+ key_list = data.get(key)
+ for (index,elem) in enumerate(key_list):
+ if ConfmlRefs.is_confml_ref(elem):
+ cref = ConfmlRefs.get_confml_ref(elem)
+ try:
+ # change None value to empty string
+ cvalue = dview.get_feature(cref).value or ''
+ if utils.is_list(cvalue):
+ cvalue = ", ".join(cvalue)
+ key_list[index] = cvalue
+ except exceptions.NotFound:
+ logging.getLogger('cone.content').error("Feature ref '%s' in include key '%s' not found." % (cref,key))
+ return data
+
+ @property
+ def include(self):
+ return self._dereference_dict(self._include)
+
+ @property
+ def exclude(self):
+ return self._dereference_dict(self._exclude)
+
+ def get_filelist(self):
+ filelist = []
+ if self.file:
+ filelist.append(self.file)
+ for elem in self.include.get('files',[]):
+ elem = elem.lower().split(',')
+ filelist += [selem.strip() for selem in elem]
+ return filelist
+
+ def get_include_pattern(self):
+ return self.include.get('pattern',[''])[0]
+
+ def get_exclude_pattern(self):
+ return self.exclude.get('pattern',[''])[0]
+
+ def get_refs(self):
+ refs = []
+ if self._dir is not None:
+ refs.extend(utils.extract_delimited_tokens(self._dir))
+ if self._file is not None:
+ refs.extend(utils.extract_delimited_tokens(self._file))
+ for value_list in self._include.itervalues():
+ for value in value_list:
+ refs.extend(utils.extract_delimited_tokens(value))
+ for value_list in self._exclude.itervalues():
+ for value in value_list:
+ refs.extend(utils.extract_delimited_tokens(value))
+ return refs
+
+
+class ExternalContentInput(ContentInput):
+ def __init__(self, **kwargs):
+ super(ExternalContentInput,self).__init__(**kwargs)
+
+class ContentParserBase(object):
+ """
+ Parses a single content implml file
+ """
+ NAMESPACES = ['http://www.s60.com/xml/content/1']
+ INCLUDE_ATTR = ['pattern']
+ EXCLUDE_ATTR = ['pattern']
+ def __init__(self):
+ self.namespaces = self.NAMESPACES
+
+ def parse_phase(self,etree):
+ phase = ""
+ phase = etree.get('phase')
+ return phase
+
+ def parse_desc(self,etree):
+ desc = ""
+ desc_elem = etree.find("{%s}desc" % self.namespaces[0])
+ if desc_elem != None:
+ desc = desc_elem.text
+ return desc
+
+ def parse_tags(self,etree):
+ tags = {}
+ for tag in etree.getiterator("{%s}tag" % self.namespaces[0]):
+ tagname = tag.get('name','')
+ tagvalue = tag.get('value')
+ values = tags.get(tagname,[])
+ values.append(tagvalue)
+ tags[tagname] = values
+ return tags
+
+ def parse_input_include(self,etree):
+ include_elem = etree.getiterator("{%s}include" % self.namespaces[0])
+ include = {}
+ for f in include_elem:
+ for key in f.keys():
+ # Add the attribute if it is found to include dict
+ include[key] = []
+ include[key].append(f.get(key))
+ return include
+
+ def parse_input_exclude(self,etree):
+ elem = etree.getiterator("{%s}exclude" % self.namespaces[0])
+ exclude = {}
+ for f in elem:
+ for key in f.keys():
+ # Add the attribute if it is found
+ exclude[key] = []
+ exclude[key].append(f.get(key))
+ return exclude
+
+class Content1Parser(ContentParserBase):
+ """
+ Parses a single content implml file
+ """
+ NAMESPACES = ['http://www.s60.com/xml/content/1']
+ def __init__(self):
+ super(ContentParserBase,self).__init__()
+ self.namespaces = self.NAMESPACES
+
+ def parse_input(self,etree):
+ input_elem = etree.find("{%s}input" % self.namespaces[0])
+ input_dir = ""
+ input_file = ""
+ if input_elem != None:
+ if input_elem.get('dir'):
+ input_dir = input_elem.get('dir')
+ if input_elem.get('file'):
+ input_dir = input_elem.get('file')
+ includes = self.parse_input_include(etree)
+ excludes = self.parse_input_exclude(etree)
+ return ContentInput(dir=input_dir, include=includes, exclude=excludes, file=input_file)
+ return None
+
+ def parse_outputs(self,etree):
+ output_elem = etree.find("{%s}output" % self.namespaces[0])
+ output_dir = ""
+ output_flatten = False
+ inputs = []
+ if output_elem != None:
+ output_dir = output_elem.get('dir','')
+ output_flatten = output_elem.get('flatten','') == "true"
+ input = self.parse_input(etree)
+ if input:
+ inputs.append(input)
+ return [ContentOutput(dir=output_dir, flatten=output_flatten, inputs=inputs)]
+
+class Content2Parser(ContentParserBase):
+ """
+ Parses a single content implml file
+ """
+ NAMESPACES = ['http://www.s60.com/xml/content/2']
+ def __init__(self):
+ super(ContentParserBase,self).__init__()
+ self.namespaces = self.NAMESPACES
+
+
+ def parse_input(self,input_elem):
+ input = None
+ input_dir = ''
+ input_file = ''
+ if input_elem != None:
+ if input_elem.get('dir'):
+ input_dir = input_elem.get('dir')
+ if input_elem.get('file'):
+ input_file= input_elem.get('file')
+ includes = self.parse_input_include(input_elem)
+ excludes = self.parse_input_exclude(input_elem)
+ input = ContentInput(dir=input_dir, include=includes, exclude=excludes, file=input_file)
+ return input
+
+ def parse_external_input(self,input_elem):
+ input = None
+ input_dir = ''
+ if input_elem != None:
+ if input_elem.get('dir'):
+ input_dir = input_elem.get('dir')
+ includes = self.parse_input_include(input_elem)
+ excludes = self.parse_input_exclude(input_elem)
+ input = ExternalContentInput(dir=input_dir, include=includes, exclude=excludes)
+ return input
+
+ def parse_outputs(self,etree):
+ outputs = []
+ for output_elem in etree.getiterator("{%s}output" % self.namespaces[0]):
+ inputs = []
+ output_dir = output_elem.get('dir','')
+ output_file = output_elem.get('file','')
+ output_flatten = output_elem.get('flatten','') == "true"
+ for input_elem in output_elem.getiterator("{%s}input" % self.namespaces[0]):
+ inputs.append(self.parse_input(input_elem))
+ for input_elem in output_elem.getiterator("{%s}externalinput" % self.namespaces[0]):
+ inputs.append(self.parse_external_input(input_elem))
+ outputs.append(ContentOutput(dir=output_dir, flatten=output_flatten, inputs=inputs, file=output_file))
+ return outputs
+
+
+class ContentImplReader(object):
+ """
+ Parses a single content implml file
+ """
+ PARSERS = {'http://www.s60.com/xml/content/1' : Content1Parser,
+ 'http://www.s60.com/xml/content/2' : Content2Parser}
+ def __init__(self):
+ self.desc = None
+ self.outputs = None
+ self.phase = None
+
+ def fromstring(self, xml_as_string):
+ etree = ElementTree.fromstring(xml_as_string)
+ # Loop through parsers and try to find a match
+ (namespace,elemname) = get_elemname(etree.tag)
+ pclass = self.PARSERS.get(namespace, None)
+ self.parser = pclass()
+ self.desc = self.parser.parse_desc(etree)
+ self.outputs = self.parser.parse_outputs(etree)
+ self.phase = self.parser.parse_phase(etree)
+ self.tags = self.parser.parse_tags(etree)
+ return
+
+namespace_pattern = re.compile("{(.*)}(.*)")
+nonamespace_pattern = re.compile("(.*)")
+
+def get_elemname(tag):
+
+ ns = namespace_pattern.match(tag)
+ nn = nonamespace_pattern.match(tag)
+ if ns:
+ namespace = ns.group(1)
+ elemname = ns.group(2)
+ return (namespace,elemname)
+ elif nn:
+ namespace = ""
+ elemname = nn.group(1)
+ return (namespace,elemname)
+ else:
+ raise exceptions.ParseError("Could not parse tag %s" % tag)
+
+class ConfmlRefs(object):
+
+ ref_pattern = re.compile('^\$\{(.*)\}$')
+ cref_pattern = re.compile('.+\..+')
+ ref_separator = '/'
+
+ @classmethod
+ def is_ref_like(cls, variableref):
+ """
+
+ Returns true if the given variable represents a ref
+ """
+ return cls.cref_pattern.match(variableref) != None
+
+ @classmethod
+ def is_confml_ref(cls, variableref):
+ """
+
+ Returns true if the given variable ref is a confml reference
+ """
+
+ pos = variableref.find(cls.ref_separator)
+ if pos == -1:
+ return cls.ref_pattern.match(variableref) != None
+ else:
+ return cls.is_confml_refs(variableref)
+
+ @classmethod
+ def is_confml_refs(cls, variableref):
+ """
+
+ Returns true if the given variable ref is a confml reference
+ """
+ ret = False
+ parts = variableref.split(cls.ref_separator)
+ for p in parts:
+ if cls.is_confml_ref(p) == True:
+ ret = True
+ return ret
+
+
+ @classmethod
+ def get_confml_ref(cls, variableref):
+ """
+
+ Returns true if the given variable ref is a confml reference
+ """
+ pos = variableref.find(cls.ref_separator)
+ if pos == -1:
+ matchref = cls.ref_pattern.match(variableref)
+ if matchref:
+ return matchref.group(1)
+ else:
+ return cls.get_confml_refs(variableref)
+
+ @classmethod
+ def get_confml_refs(cls, variableref):
+ """
+
+ Returns an array of confml refs based on variableref
+ """
+ parts = variableref.split(cls.ref_separator)
+ ret = []
+ for p in parts:
+ matchref = cls.ref_pattern.match(p)
+ if matchref:
+ ref = matchref.group(1)
+ if not ref in ret:
+ ret.append(matchref.group(1))
+ else:
+ ret.append(p)
+ return ret
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/CTD_Special.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/CTD_Special.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/CVC_Content.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/CVC_Content.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/content.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/content.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/content/test/override.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/content/test/override.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+S60 default
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/content/test/s60.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/content/test/s60.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+hey!!
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/content/test/test_CAP_letters.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/content/test/test_CAP_letters.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+S60 default
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/content2_with_multi_outputs.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/content2_with_multi_outputs.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/content2_with_tags.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/content2_with_tags.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/content2_with_tags_refs.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/content2_with_tags_refs.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/copy.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/copy.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+ Copy content.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/copy_files.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/copy_files.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/file_refs.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/file_refs.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_capital_file_input.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_capital_file_input.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_refs.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_refs.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_refs2.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_refs2.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_refs3.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_refs3.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_sequence_refs.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_content_with_sequence_refs.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_external_input.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_external_input.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ Copy only prod
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_external_with_ref.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_external_with_ref.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+ Copy test file
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_filter_both.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_filter_both.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+ Copy only prod
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/root.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/external_content/abc.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/external_content/folder1/data.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/external_content/folder1/folder2/setting.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/content/test/override.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/content/test/override.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+NCP11 override
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/content/test/shout.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/content/test/shout.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Shout out!
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/prodX/jee/ProdX_specific.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/prodX/jee/ProdX_specific.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+földska
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/root.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/root.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/product.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/product.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_confmlrefs.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_confmlrefs.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import pkg_resources
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+try:
+ pkg_resources.require('ConeContentPlugin')
+except pkg_resources.DistributionNotFound:
+ import __init__
+
+from contentplugin import contentmlparser
+
+class TestConfmlRefs(unittest.TestCase):
+
+ def test_is_confml_ref_of_plain_string(self):
+ self.assertFalse(contentmlparser.ConfmlRefs.is_confml_ref('foo.bar'))
+
+ def test_is_confml_ref_of_variable_string(self):
+ self.assertTrue(contentmlparser.ConfmlRefs.is_confml_ref('${foo.bar}'))
+
+ def test_is_confml_ref_of_variable_string_with_dollar(self):
+ self.assertTrue(contentmlparser.ConfmlRefs.is_confml_ref('${features.foo$bar}'))
+
+ def test_get_confml_ref_with_normal_ref(self):
+ self.assertEquals(contentmlparser.ConfmlRefs.get_confml_ref('${features.foo.bar}'), 'features.foo.bar')
+
+ def test_get_confml_ref_with_invalid_ref(self):
+ self.assertEquals(contentmlparser.ConfmlRefs.get_confml_ref('${features.foo.bar'), None)
+
+ def test_get_two_confml_refs(self):
+ self.assertTrue(contentmlparser.ConfmlRefs.is_ref_like('ab.cd'))
+ self.assertTrue(contentmlparser.ConfmlRefs.is_confml_ref('${features.foo.bar}/${features.foo.bar2}'))
+ self.assertEquals(contentmlparser.ConfmlRefs.get_confml_refs('${features.foo.bar}/${features.foo.bar2}'), ['features.foo.bar', 'features.foo.bar2'])
+ self.assertEquals(contentmlparser.ConfmlRefs.get_confml_refs('${features.foo.bar}/${features.foo.bar}'), ['features.foo.bar'])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_copy.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_copy.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os
+import pkg_resources
+try:
+ pkg_resources.require('ConeContentPlugin')
+except pkg_resources.DistributionNotFound:
+ import __init__
+
+from cone.public.exceptions import NotSupportedException
+from contentplugin import contentml
+
+class TestCreateContentPlugin(unittest.TestCase):
+ def test_create_content_impl(self):
+ imp = contentml.ContentImpl('test.content',None)
+ pass
+
+class TestContentImplementation(unittest.TestCase):
+ def setUp(self):
+ self.imp = contentml.ContentImpl('test.content',None)
+ pass
+
+ def test_content_filter(self):
+ files = ['aaa.txt', 'bbb.txt']
+ filesfunc = lambda x: x.lower() in [file.lower() for file in files]
+ self.assertEquals(filesfunc('aaa'), False)
+ self.assertEquals(filesfunc('AAA'), False)
+ self.assertEquals(filesfunc('AAA.txt'), True)
+ self.assertEquals(filesfunc('aaa.txt'), True)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,345 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import pkg_resources
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+try:
+ pkg_resources.require('ConeContentPlugin')
+except pkg_resources.DistributionNotFound:
+ import __init__
+
+from contentplugin import contentmlparser
+
+
+invalidxml_string = ''
+
+contentml_string = \
+'''
+
+
+
+
+ Description field text
+
+
+
+
+
+ '''
+
+contentml_files_string = '''
+
+ Description field text
+
+
+
+
+
+'''
+
+contentml_string_with_phase = \
+''\
+''\
+' Description field text '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '
+
+
+contentml_brief = \
+''\
+''\
+' '\
+' '\
+' '
+
+contentml_brief2 = \
+''\
+''\
+' '
+
+
+contentml_with_refs = \
+''\
+''\
+' Description field text '\
+' '\
+' '\
+' '\
+' '\
+' '
+
+contentml2_string = \
+'''
+
+
+
+
+ Description field text
+
+
+
+
+
+
+
+
+
+
+
+ '''
+
+content2_multi = '''
+
+
+
+
+
+
+
+
+
+
+ '''
+
+external_content_multi = '''
+
+ Copy only prod
+
+
+
+
+
+
+
+
+
+ '''
+
+
+
+
+class TestContentParseimpl(unittest.TestCase):
+
+ def test_parse_desc(self):
+ etree = ElementTree.fromstring(contentml_string)
+ reader = contentmlparser.Content1Parser()
+ desc = reader.parse_desc(etree)
+ self.assertEquals(desc,'Description field text')
+
+ def test_parse_output(self):
+ etree = ElementTree.fromstring(contentml_string)
+ reader = contentmlparser.Content1Parser()
+ output = reader.parse_outputs(etree)
+ self.assertEquals(output[0].dir,'content')
+
+ def test_parse_input_dir(self):
+ etree = ElementTree.fromstring(contentml_string)
+ reader = contentmlparser.Content1Parser()
+ input = reader.parse_input(etree)
+ self.assertEquals(input.dir,'test')
+
+ def test_parse_input_include(self):
+ etree = ElementTree.fromstring(contentml_string)
+ reader = contentmlparser.Content1Parser()
+ include = reader.parse_input_include(etree)
+ self.assertEquals(include,{'pattern': ['prod']})
+
+ def test_parse_input_files(self):
+ etree = ElementTree.fromstring(contentml_files_string)
+ reader = contentmlparser.Content1Parser()
+ include = reader.parse_input_include(etree)
+ self.assertEquals(include,{'files': ['test/foobar.txt, test/bar.txt']})
+
+ def test_parse_input_include_not_found(self):
+ etree = ElementTree.fromstring(contentml_brief)
+ reader = contentmlparser.Content1Parser()
+ include = reader.parse_input_include(etree)
+ self.assertEquals(include,{})
+
+ def test_parse_input_exclude(self):
+ etree = ElementTree.fromstring(contentml_string)
+ reader = contentmlparser.Content1Parser()
+ include = reader.parse_input_exclude(etree)
+ self.assertEquals(include,{'pattern': ['.svn']})
+
+ def test_parse_input_exclude_not_found(self):
+ etree = ElementTree.fromstring(contentml_brief)
+ reader = contentmlparser.Content1Parser()
+ include = reader.parse_input_exclude(etree)
+ self.assertEquals(include,{})
+
+ def test_parse_tags(self):
+ etree = ElementTree.fromstring(contentml_string)
+ reader = contentmlparser.Content1Parser()
+ tags = reader.parse_tags(etree)
+ self.assertEquals(tags,{'target' : ['core','rofs3'],
+ 'test' : ['foo']})
+
+class TestContent2Parseimpl(unittest.TestCase):
+
+ def test_parse_desc(self):
+ etree = ElementTree.fromstring(contentml2_string)
+ reader = contentmlparser.Content2Parser()
+ desc = reader.parse_desc(etree)
+ self.assertEquals(desc,'Description field text')
+
+ def test_parse_outputs(self):
+ etree = ElementTree.fromstring(contentml2_string)
+ reader = contentmlparser.Content2Parser()
+ outputs = reader.parse_outputs(etree)
+ self.assertEquals(outputs[0].dir,'content')
+ self.assertEquals(len(outputs[0].inputs),1)
+ self.assertEquals(outputs[0].inputs[0].dir,'test')
+ self.assertEquals(outputs[0].inputs[0].include,{'pattern': ['prod']})
+ self.assertEquals(outputs[1].inputs[0].dir,'${features.inputref}')
+ self.assertEquals(outputs[1].dir,'${features.outputref}')
+
+
+class TestContentParser(unittest.TestCase):
+ def test_parse_from_string(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(contentml_string)
+ self.assertEquals(reader.desc,'Description field text')
+ self.assertEquals(reader.outputs[0].dir,'content')
+ self.assertEquals(reader.outputs[0].inputs[0].dir,'test')
+ self.assertEquals(reader.outputs[0].inputs[0].include, {'pattern':['prod']})
+ self.assertEquals(reader.outputs[0].inputs[0].exclude, {'pattern':['.svn']})
+ self.assertEquals(reader.phase, None)
+ self.assertEquals(reader.tags, {'target' : ['core','rofs3'],
+ 'test' : ['foo']})
+
+ def test_parse_from_string_with_phase(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(contentml_string_with_phase)
+ self.assertEquals(reader.desc,'Description field text')
+ self.assertEquals(reader.outputs[0].dir,'content')
+ self.assertEquals(reader.outputs[0].inputs[0].dir,'test')
+ self.assertEquals(reader.outputs[0].inputs[0].include, {'pattern':['prod']})
+ self.assertEquals(reader.outputs[0].inputs[0].exclude, {'pattern':['.svn']})
+ self.assertEquals(reader.phase, 'pre')
+
+ def test_parse_from_string_brief(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(contentml_brief)
+ self.assertEquals(reader.desc,"")
+ self.assertEquals(reader.outputs[0].dir,'content')
+ self.assertEquals(reader.outputs[0].inputs[0].dir,'test')
+ self.assertEquals(reader.outputs[0].inputs[0].include, {})
+ self.assertEquals(reader.outputs[0].inputs[0].exclude, {})
+
+ def test_parse_from_string_brief2(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(contentml_brief2)
+ self.assertEquals(reader.desc,"")
+ self.assertEquals(reader.outputs[0].dir,"")
+ self.assertEquals(len(reader.outputs[0].inputs),0)
+
+ def test_parse_from_string_with_refs(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(contentml_with_refs)
+
+ self.assertEquals(reader.outputs[0].dir,"${features.outputref}")
+ self.assertEquals(reader.outputs[0].inputs[0].dir,"${features.inputref}")
+ self.assertEquals(reader.outputs[0].inputs[0].include, {'pattern': ['${features.inputfilter}']} )
+
+ def test_content2_parse_outputs(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(contentml2_string)
+ self.assertEquals(reader.outputs[0].dir,'content')
+ self.assertEquals(len(reader.outputs[0].inputs),1)
+ self.assertEquals(reader.outputs[0].inputs[0].dir,'test')
+ self.assertEquals(reader.outputs[0].inputs[0].include,{'pattern': ['prod']})
+ self.assertEquals(reader.outputs[1].inputs[0].dir,'${features.inputref}')
+ self.assertEquals(reader.outputs[1].dir,'${features.outputref}')
+ self.assertEquals(reader.tags, {'target' : ['core','rofs3'],
+ 'test' : ['foo']})
+
+ def test_content2_parse_multi(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(content2_multi)
+ self.assertEquals(reader.outputs[0].dir,'content')
+ self.assertEquals(len(reader.outputs[0].inputs),1)
+ self.assertEquals(reader.outputs[0].inputs[0].dir,'')
+ self.assertEquals(reader.outputs[0].inputs[0].include,{'files': ['test/override.txt, test/s60.txt']})
+ self.assertEquals(reader.outputs[1].inputs[0].file,'test/s60.txt')
+ self.assertEquals(reader.outputs[1].inputs[0].get_filelist(),['test/s60.txt'])
+
+ def test_external_content_parse_multi(self):
+ reader = contentmlparser.ContentImplReader()
+ reader.fromstring(external_content_multi)
+ self.assertEquals(reader.outputs[0].dir,'content')
+ self.assertEquals(len(reader.outputs[0].inputs),1)
+ self.assertEquals(len(reader.outputs[1].inputs),1)
+ self.assertEquals(reader.outputs[0].inputs[0].dir,'external_content/folder1')
+ self.assertEquals(reader.outputs[0].inputs[0].include,{})
+ self.assertEquals(reader.outputs[1].inputs[0].dir,'external_content')
+ self.assertEquals(reader.outputs[1].inputs[0].include,{'pattern': ['.txt']})
+
+
+class TestContentOutput(unittest.TestCase):
+ def test_content_output_dir(self):
+ conout = contentmlparser.ContentOutput(dir='foobar/test')
+ self.assertEquals(conout.dir, 'foobar/test')
+
+ def test_content_output_include(self):
+ conout = contentmlparser.ContentOutput(flatten=True)
+ self.assertEquals(conout.flatten, True)
+
+ def test_path_convert(self):
+ conout = contentmlparser.ContentOutput()
+ self.assertEquals(conout.path_convert('z:\\test\\foo\\bar.txt'), 'test\\foo\\bar.txt')
+ self.assertEquals(conout.path_convert('z:/test/foo/bar.txt'), 'test/foo/bar.txt')
+
+class TestContentInput(unittest.TestCase):
+ def test_content_input_dir(self):
+ conin = contentmlparser.ContentInput(dir='foobar/test')
+ self.assertEquals(conin.dir, 'foobar/test')
+
+ def test_content_include_pattern(self):
+ conin = contentmlparser.ContentInput(include={'pattern':['foo','bar']})
+ self.assertEquals(conin.get_include_pattern(), 'foo')
+
+ def test_content_exclude_pattern(self):
+ conin = contentmlparser.ContentInput(exclude={'pattern':['foo','bar']})
+ self.assertEquals(conin.get_exclude_pattern(), 'foo')
+
+ def test_parse_invalid_xml(self):
+ try:
+ etree = ElementTree.fromstring(invalidxml_string)
+ self.fail('Parsing invalid xml succeeds?')
+ except:
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,261 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import logging
+import __init__
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from contentplugin import contentml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'contentproject')
+
+
+class TestContentPlugin(unittest.TestCase):
+
+ def test_create_copy_list_from_datacontainer_with_test(self):
+ '''
+ Test that the loading of the plugins works
+ '''
+ data = container.DataContainer()
+ data.add_value('test/test.txt','/foo/content/test/test.txt')
+ data.add_value('test/test.txt','/bar/content/test/test.txt')
+ data.add_value('product/aaa.txt','/foo/content/product/aaa.txt')
+ data.add_value('images/kuva.jpg','/foo/content/images/kuva.jpg')
+ data.add_value('include/hide.iby','/bar/content/include/hide.iby')
+ impl = contentml.ContentImpl("foo",None)
+ copylist = impl.create_copy_list(content=data, input='test',output='content')
+ self.assertEquals(copylist[0][1],'content/test.txt')
+
+ def test_create_copy_list_from_datacontainer_with_defauls(self):
+ '''
+ Test that the loading of the plugins works
+ '''
+ data = container.DataContainer()
+ data.add_value('test/test.txt','/foo/content/test/test.txt')
+ data.add_value('test/test.txt','/bar/content/test/test.txt')
+ data.add_value('product/aaa.txt','/foo/content/product/aaa.txt')
+ data.add_value('images/kuva.jpg','/foo/content/images/kuva.jpg')
+ data.add_value('include/hide.iby','/bar/content/include/hide.iby')
+ impl = contentml.ContentImpl("foo",None)
+ copylist = impl.create_copy_list(content=data)
+ self.assertEquals(copylist[0][0],'/bar/content/test/test.txt')
+ self.assertEquals(copylist[0][1],'test/test.txt')
+ self.assertEquals(copylist[1][0],'/bar/content/include/hide.iby')
+ self.assertEquals(copylist[1][1],'include/hide.iby')
+
+ def test_create_copy_list_from_datacontainer_with_filters(self):
+ '''
+ Test that the loading of the plugins works
+ '''
+ data = container.DataContainer()
+ data.add_value('test/test.txt','/foo/content/test/test.txt')
+ data.add_value('test/test.txt','/bar/content/test/test.txt')
+ data.add_value('product/aaa.txt','/foo/content/product/aaa.txt')
+ data.add_value('images/kuva.jpg','/foo/content/images/kuva.jpg')
+ data.add_value('include/hide.iby','/bar/content/include/hide.iby')
+ impl = contentml.ContentImpl("foo",None)
+ copylist = impl.create_copy_list(content=data,input='include',include_filter='*.iby')
+ self.assertEquals(copylist[0][0],'/bar/content/include/hide.iby')
+ self.assertEquals(copylist[0][1],'hide.iby')
+
+class TestContentPluginOnFileStorage(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = 'output'
+ self.workdir = 'workdir'
+ if not os.path.exists(self.workdir):
+ os.mkdir(self.workdir)
+ os.chdir(self.workdir)
+ pass
+
+ def tearDown(self):
+ os.chdir(self.curdir)
+ if os.path.exists(self.workdir):
+ shutil.rmtree(self.workdir)
+ pass
+
+ def load_config(self, config='product.confml'):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ return p.get_configuration(config)
+
+ def load_impl(self, resource_ref, config='product.confml'):
+ configuration = self.load_config(config)
+ impls = plugin.ImplFactory.get_impls_from_file(resource_ref, configuration)
+ self.assertEquals(len(impls), 1)
+ impl = impls[0]
+ impl.set_output_root(self.output)
+ return impl
+
+ def test_configuration_parse_resource(self):
+ impl = self.load_impl('assets/s60/implml/test_filter_both.content')
+ self.assertEquals(impl.outputs[0].dir,'content')
+ self.assertEquals(impl.outputs[0].inputs[0].include,{'pattern': ['prod']})
+ self.assertEquals(impl.outputs[0].inputs[0].exclude,{'pattern': ['.svn']})
+ self.assertEquals(impl.get_tags(), {'target': ['rofs3', 'uda']})
+ self.assertEquals(impl.has_tag({'target':['rofs3']}), True)
+
+
+ def test_configuration_parse_content2(self):
+ impl = self.load_impl('assets/s60/implml/content2_with_tags.content')
+ self.assertEquals(impl.outputs[0].dir,'content')
+ self.assertEquals(impl.outputs[0].inputs[0].include,{'files': ['test/override.txt, test/s60.txt']})
+ self.assertEquals(impl.get_tags(), {'target': ['rofs3', 'uda']})
+ self.assertEquals(impl.has_tag({'target':['rofs3']}), True)
+
+ def test_configuration_parse_content2_with_tag_refs(self):
+ impl = self.load_impl('assets/s60/implml/content2_with_tags_refs.content')
+ self.assertEquals(impl.get_tags(), {'target': ['rofs3']})
+ self.assertEquals(impl.has_tag({'target':['rofs3']}), True)
+
+ def test_configuration_parse_and_filter_implementation_with_tags(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impls = plugin.get_impl_set(config,'\.content$')
+ impls_rofs3 = impls.filter_implementations(tags={'target':['rofs3']})
+ self.assertEquals(len(list(impls_rofs3)),3)
+
+ def test_configuration_parse_content_with_include_files(self):
+ impl = self.load_impl('assets/s60/implml/copy_files.content')
+ self.assertEquals(impl.outputs[0].inputs[0].include['files'],['test/override.txt, test/s60.txt'])
+
+ def test_configuration_content_get_full_copy_list(self):
+ impl = self.load_impl('assets/s60/implml/copy_files.content')
+ files = impl.get_full_copy_list()
+ self.assertEquals(files[0],('family/content/test/override.txt', 'output/content/test/override.txt', False))
+
+ def test_configuration_content_list_output_files(self):
+ config = self.load_config()
+ impls = plugin.get_impl_set(config,'\.content$')
+ impls.output = self.output
+ files = impls.list_output_files()
+ self.assertTrue('output/content/test/override.txt' in files)
+
+ def test_configuration_content_list_output_files_with_refs_filter(self):
+ impl = self.load_impl('assets/s60/implml/test_content_with_sequence_refs.content')
+ files = impl.list_output_files()
+ self.assertEquals(files[0],'output/content/override.txt')
+
+ def test_configuration_content_list_output_files_with_exclude_filter(self):
+ impl = self.load_impl('assets/s60/implml/test_filter_both.content')
+ files = impl.list_output_files()
+ self.assertEquals(files[0],'output/content/prodX/jee/ProdX_specific.txt')
+#
+ def test_configuration_get_input_with_ref(self):
+ impl = self.load_impl('assets/s60/implml/test_content_with_refs.content')
+ self.assertEquals(impl.outputs[0].dir, 'content')
+ self.assertEquals(impl.outputs[0].inputs[0].dir, 'content')
+
+ def test_configuration_get_include_with_refs(self):
+ impl = self.load_impl('assets/s60/implml/test_content_with_sequence_refs.content')
+ self.assertEquals(impl.outputs[0].inputs[0].include['files'], ['test/override.txt'])
+ self.assertEquals(impl.list_output_files(), ['output/content/override.txt'])
+
+ def test_configuration_get_include_with_refs(self):
+ impl = self.load_impl('assets/s60/implml/copy.content')
+ expected = ['output/content/prodX/jee/ProdX_specific.txt',
+ 'output/content/test/shout.txt',
+ 'output/content/test/override.txt',
+ 'output/content/test/s60.txt',
+ 'output/content/test/test_CAP_letters.txt']
+ actual = impl.list_output_files()
+ self.assertEquals(sorted(actual), sorted(expected))
+
+ def test_configuration_content_create_output(self):
+ impl = self.load_impl('assets/s60/implml/copy.content')
+ impl.set_output_root(self.output)
+ impl.logger.setLevel(logging.DEBUG)
+ impl.create_output()
+ self.assertTrue(os.path.exists(impl.output))
+ self.assertTrue(os.path.exists(os.path.join(impl.output,'content/prodX/jee/ProdX_specific.txt')))
+
+ def test_configuration_content_generate(self):
+ config = self.load_config()
+ impls = plugin.get_impl_set(config,'\.content$')
+ impls.output = self.output
+ results = impls.generate()
+ self.assertTrue(os.path.exists(impls.output))
+ self.assertTrue(os.path.exists(os.path.join(impls.output,'content/prodX/jee/ProdX_specific.txt')))
+
+ def test_configuration_content_generate_with_include_refs(self):
+ impl = self.load_impl('assets/s60/implml/test_content_with_sequence_refs.content')
+ impl.set_output_root(self.output)
+ results = impl.generate()
+ self.assertTrue(os.path.exists(impl.output))
+ self.assertTrue(os.path.exists(os.path.join(impl.output,'content/override.txt')))
+
+ def test_configuration_content_generate_with_multi_output(self):
+ impl = self.load_impl('assets/s60/implml/content2_with_multi_outputs.content')
+ impl.set_output_root(self.output)
+ results = impl.generate()
+ self.assertTrue(os.path.exists(impl.output))
+ self.assertTrue(os.path.exists(os.path.join(impl.output,'content/test/override.txt')))
+ self.assertTrue(os.path.exists(os.path.join(impl.output,'include/s60.txt')))
+
+ def test_configuration_content_generate_with_refs(self):
+ impl = self.load_impl('assets/s60/implml/test_content_with_refs2.content')
+ impl.set_output_root(self.output)
+ results = impl.generate()
+ self.assertTrue(os.path.exists(impl.output))
+ self.assertTrue(os.path.exists(os.path.join(impl.output,'content2p1/content2p2/override.txt')))
+
+ def test_configuration_content_generate_with_refs2(self):
+ impl = self.load_impl('assets/s60/implml/test_content_with_refs3.content')
+ impl.set_output_root(self.output)
+ results = impl.generate()
+ self.assertTrue(os.path.exists(impl.output))
+ self.assertTrue(os.path.exists(os.path.join(impl.output,'example/content2p2/override.txt')))
+
+ def test_configuration_content_generate_capital_letters(self):
+ impl = self.load_impl('assets/s60/implml/test_content_capital_file_input.content')
+ impl.set_output_root(self.output)
+ results = impl.generate()
+ self.assertTrue(os.path.exists(impl.output))
+ self.assertTrue(os.path.exists(os.path.join(impl.output,'content/test_CAP_letters.txt')))
+
+ def test_get_refs(self):
+ def check(filename, expected_refs):
+ impl = self.load_impl('assets/s60/implml/' + filename)
+ actual_refs = impl.get_refs()
+
+ if expected_refs is None:
+ self.assertEquals(actual_refs, None)
+ else:
+ self.assertTrue(actual_refs is not None)
+ self.assertEquals(sorted(actual_refs), sorted(expected_refs))
+
+ check('content2_with_multi_outputs.content', None)
+ check('content2_with_tags_refs.content', None)
+ check('content2_with_tags.content', None)
+ check('copy_files.content', None)
+ check('copy.content', None)
+ check('test_content_with_refs.content', ['content.inputdir'])
+ check('test_content_with_refs2.content', ['content.inputdir2'])
+ check('test_content_with_refs3.content', ['content.inputdir2'])
+ check('test_content_with_sequence_refs.content', ['ContentFiles.contentfile.fileelem.localPath'])
+ check('test_external_input.content', None)
+ check('test_external_with_ref.content', ['CTD_Special.InputPath'])
+ check('test_filter_both.content', None)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeContentPlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from contentplugin import __version__
+
+setup(
+ name = "conecontentplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "contentplugin.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine Content copier plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware", # project home page, if any
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['contentml_1 = contentplugin.contentml:ContentImplReader1',
+ 'contentml_2 = contentplugin.contentml:ContentImplReader2']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
+
+
+import pkg_resources
+import sys,os
+
+try:
+ pkg_resources.require("Cone")
+except pkg_resources.DistributionNotFound:
+ ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+ sys.path.append(ROOT_PATH)
+ sys.path.append(os.path.join(ROOT_PATH,'..'))
+ sys.path.append(os.path.join(ROOT_PATH,'../..'))
+ sys.path.append(os.path.join(ROOT_PATH,'../../..'))
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/accesspoint_id_counter.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/accesspoint_id_counter.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,365 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+Ruleml eval extension to count accesspoint id's
+'''
+
+import logging
+
+logger = logging.getLogger('cone.ruleplugin.evals.accesspoint_id_counter')
+
+def get_apindex_by_apname(aps, dns, apname):
+ """
+ Returns AccessPoint index by given AccessPoint name
+ """
+ cnt = _get_ApDnContainer_(aps, dns)
+ return cnt.get_apindex_by_apname(apname)
+
+def get_apid_by_apname(aps, dns, apname, wlan_support=True):
+ """
+ Returns AccessPoint id by given AccessPoint name
+ """
+ cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+ return cnt.get_apid_by_apname(apname)
+
+def get_dnid_by_dnname(aps, dns, dnname, wlan_support=True):
+ """
+ Return DestinationNetwork id by given DestinationNetworks name
+ """
+ cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+ return cnt.get_dnid_by_dnname(dnname)
+
+def get_apid_by_dnname_and_apname(aps, dns, dnname, apname, wlan_support=True):
+ """
+ Returns AccessPoint id by given DestinationNetwork name and AccessPoint name.
+ """
+ cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+ return cnt.get_apid_by_dnname_and_apname(dnname, apname)
+
+def get_all_in_array(aps, dns, wlan_support=True):
+ """
+ Returns array containing all data:
+ [DN name],[DN id], [IAPS names], [IAPS ids], [IAPS indexes]
+ """
+ cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+ return cnt.get_all_in_array()
+
+def _get_ApDnContainer_(aps, dns, wlan_support=True):
+ """
+ Returns populated ApDnContainer
+ """
+ cnt = ApDnContainer()
+
+ _read_dns_(dns, cnt)
+ _read_aps_(aps, cnt)
+
+ cnt._calc_dn_ids_()
+
+ if wlan_support:
+ cnt._calc_ap_ids_(2)
+ else:
+ cnt._calc_ap_ids_(1)
+
+ cnt._calc_ap_indexes_(1)
+
+ return cnt
+
+def _read_dns_(dns, cnt):
+ """
+ Reads DNs to internal objects to ApDnContainer.
+ """
+
+ dn_names = None
+ dn_ids = None
+ dn_iaps = [None]*10
+
+ for dn in dns.DN:
+ if dn.ref == 'Name':
+ dn_names = dn.value
+ if dn.ref == 'DNId':
+ dn_ids = dn.value
+ if dn.ref == 'IAP':
+ dn_iaps[0] = dn.value
+ if dn.ref == 'IAP2':
+ dn_iaps[1] = dn.value
+ if dn.ref == 'IAP3':
+ dn_iaps[2] = dn.value
+ if dn.ref == 'IAP4':
+ dn_iaps[3] = dn.value
+ if dn.ref == 'IAP5':
+ dn_iaps[4] = dn.value
+ if dn.ref == 'IAP6':
+ dn_iaps[5] = dn.value
+ if dn.ref == 'IAP7':
+ dn_iaps[6] = dn.value
+ if dn.ref == 'IAP8':
+ dn_iaps[7] = dn.value
+ if dn.ref == 'IAP9':
+ dn_iaps[8] = dn.value
+ if dn.ref == 'IAP10':
+ dn_iaps[9] = dn.value
+
+ logger.info('Parsed DN names: %s' % dn_names)
+ logger.info('Parsed DN ids: %s' % dn_ids)
+ logger.info('Parsed DN iaps: %s' % dn_iaps)
+
+ for i in range(len(dn_names)):
+ mydn = Dn()
+ mydn.set_id(dn_ids[i])
+ mydn.set_name(dn_names[i])
+ myiaps = [None]*10
+ for j in range(10):
+ myiaps[j] = dn_iaps[j][i]
+ mydn.set_iaps(myiaps)
+ cnt.add_dn(mydn)
+ return cnt
+
+def _read_aps_(aps, cnt):
+ """
+ Reads APs to internal objects to ApDnContainer.
+ """
+ ap_names = None
+ ap_ids1 = None
+
+ for ap in aps.AP:
+ if ap.ref == 'ConnectionName':
+ ap_names = ap.value
+ if ap.ref == 'ConnectionId':
+ ap_ids1 = ap.value
+
+ ap_ids2 = [None]*len(ap_names)
+ if ap_ids1 == None:
+ ap_ids1 = []
+
+
+ for i in range(len(ap_ids1)):
+ ap_ids2[i] = ap_ids1[i]
+
+
+ logger.info('Parsed AP names: %s' % ap_names)
+ logger.info('Parsed AP ids: %s' % ap_ids2)
+
+ for i in range(len(ap_names)):
+ myap = Ap()
+ myap.set_id(ap_ids2[i])
+ myap.set_name(ap_names[i])
+ cnt.add_ap(myap)
+ return cnt
+
+def _get_next_free_id_(bases, start_index=1):
+ """
+ Returns next id as a string that is not in use.
+ """
+
+ biggest_id = int(start_index)
+
+ for base in bases:
+ current_id = base.get_id()
+ if current_id != None or current_id != '':
+ if current_id > biggest_id:
+ biggest_id = current_id
+
+ return str(int(biggest_id) + 1)
+
+
+class ApDnContainer(object):
+ """
+ Container for AccessPoints and DestinationNetworks, that provides various access and search methods to them.
+ """
+
+ def __init__(self):
+ self.dns = []
+ self.aps = []
+
+ def __str__(self):
+ return "ApDnContainer(dns: " + str(self.dns) + ", aps:" + str(self.aps) + ")"
+
+ def add_dn(self, dn):
+ self.dns.append(dn)
+
+ def add_ap(self, ap):
+ self.aps.append(ap)
+
+ def get_all_dns(self):
+ return self.dns
+
+ def get_all_aps(self):
+ return self.aps
+
+ def _calc_dn_ids_(self):
+ for dn in self.dns:
+ if dn.get_id() == None or dn.get_id() == '':
+ dn.set_id(_get_next_free_id_(self.dns, 1))
+
+ def _calc_ap_indexes_(self, ind=1):
+ index = ind
+
+ for dn in self.dns:
+ for iap in dn.get_iaps():
+ if iap != None:
+ for ap in self.aps:
+ if ap.get_name() == iap and ap.get_index() == '':
+ ap.set_index(str(index))
+ index += 1
+
+ def _calc_ap_ids_(self, start_index=1):
+ """
+ Calculates unique index for every AccessPoint, if Easy_WLAN is given it always have index 1.
+ """
+
+ for ap in self.aps:
+ if ap.name == 'Easy WLAN':
+ ap.set_id('1')
+ logger.info('Easy_WLAN AP found. Setting 1 to AP id.')
+
+ for ap in self.aps:
+ if ap.get_id() == None or ap.get_id() == '':
+ ap.set_id(_get_next_free_id_(self.aps, int(start_index)))
+
+ def get_apid_by_apname(self, apname):
+ """
+ Returns Accesspoint id by given AccessPoint name
+ """
+
+ for ap in self.aps:
+ if ap.name == apname:
+ return ap.get_id()
+ return None
+
+ def get_apindex_by_apname(self, apname):
+ """
+ Returns Accesspoint index by given AccessPoint name
+ """
+
+ for ap in self.aps:
+ if ap.get_name() == apname:
+ return ap.get_index()
+ return None
+
+
+ def get_dnid_by_dnname(self, dnname):
+ """
+ Return DestinationNetwork id by given DestinationNetworks name
+ """
+ for dn in self.dns:
+ if dn.name == dnname:
+ return dn.id
+ return None
+
+ def get_apid_by_dnname_and_apname(self, dnname, apname):
+ """
+ Returns AccessPoint id by given DestinationNetwork name and AccessPoint name.
+ """
+ for dn in self.dns:
+ if dn.name == dnname:
+ iaps = dn.get_iaps()
+ for iap in range(len(iaps)):
+ if iaps[iap] != None and iaps[iap] == apname:
+ return self.get_apid_by_apname(apname)
+ return None
+
+ def get_all_in_array(self):
+ """
+ Returns array containing all data:
+ [DN name],[DN id], [IAPS names], [IAPS ids] [IAPS index]
+ """
+ ret = [None]*len(self.dns)
+
+ for i in range(len(self.dns)):
+ line = [None]*5
+ line[0] = self.dns[i].get_name()
+ line[1] = self.dns[i].get_id()
+ line[2] = self.dns[i].get_iaps()
+
+ ap_ids = [None]*10
+
+ for j in range(10):
+ ap_ids[j] = self.get_apid_by_apname(self.dns[i].get_iaps()[j])
+
+ line[3] = ap_ids
+
+ ap_indexes = [None]*10
+
+ for j in range(10):
+ ap_indexes[j] = self.get_apindex_by_apname(self.dns[i].get_iaps()[j])
+
+ line[4] = ap_indexes
+
+ ret[i] = line
+
+ return ret
+
+class Base(object):
+ """
+ Base data classes for AP and DN classes.
+ """
+ def __init__(self):
+ self.name = ''
+ self.id = ''
+
+ def set_name(self, name):
+ self.name = name
+
+ def get_name(self):
+ return self.name
+
+ def set_id(self, id):
+ self.id = id
+
+ def get_id(self):
+ return self.id
+
+class Dn(Base):
+ """
+ Destination network
+ """
+
+ def __init__(self):
+ self.name = None
+ self.id = None
+ self.iaps = [None]*10
+
+ def __str__(self):
+ return "Dn(name: " + self.name + ", id:" + self.id + ", iaps:" + str(self.iaps) + ")"
+
+ def set_iaps(self, iaps):
+ self.iaps = iaps
+
+ def set_iap(self, index, value):
+ self.iaps[index] = value
+
+ def get_iap(self, index):
+ return self.iaps[index]
+
+ def get_iaps(self):
+ return self.iaps
+
+class Ap(Base):
+
+ def __init__(self):
+ self.name = ''
+ self.id = ''
+ self.index = ''
+
+ def __str__(self):
+ return "Ap(name: " + self.name + ", id:" + self.id + ")"
+
+ def set_index(self, index):
+ self.index = index
+
+ def get_index(self):
+ return self.index
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/layer_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/layer_utils.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,119 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+'''
+Ruleml eval extension to check is passed ref changed on given layer(range).
+'''
+
+from cone.public import api
+
+import logging
+
+logger = logging.getLogger('cone.ruleplugin.evals.layer_utils')
+
+def give_changed_layers(feat):
+ """
+ Returns a list of booleans where True means that feature is changed in that layer. Index is
+ same than in configuration root's get_configuration_by_index().
+ """
+
+ logger.debug('Checking feature: %s' % feat.fqr)
+
+ root_conf = feat.get_root_configuration()
+ nro_of_layers = len(root_conf.list_configurations())
+ result = [False] * nro_of_layers
+
+ for i in range(0, nro_of_layers):
+ conf = root_conf.get_configuration_by_index(i)
+ logger.debug("Traversing data from configuration: %s" % conf.get_path())
+ datas = conf._traverse(type=api.Data, filters=[lambda d: d.fqr==feat.fqr])
+ for data in datas:
+ try:
+ if data.get_value() != None:
+ logger.debug("Feature '%s' is changed in layer %s with data '%s'" % (feat.fqr, i, data.get_value()))
+ result[i] = True
+ except Exception, e:
+ logger.debug("Failed to check Feature '%s' data in layer %s:", (e,i))
+ if result[i] == False:
+ logger.debug("Feature '%s' is not changed in layer: %s" % (feat.fqr, i))
+ logger.debug("Feature '%s' is changed in layers: %s" % (feat.fqr, result))
+ return result
+
+def changed_on_last_layer(feat):
+ """
+ Returns True if feature is changed in the last layer.
+ """
+
+ root_conf = feat.get_root_configuration()
+ conf = root_conf.get_configuration_by_index(-2)#autoconfig layer is ignored
+
+ def check(node):
+ if isinstance(node, api.Data) and node.fqr == feat.fqr:
+ return True
+ for obj in node._objects():
+ if check(obj):
+ return True
+
+ if check(conf):
+ return True
+ else:
+ return False
+
+def changed_on_autoconfig_layer(feat):
+ """
+ Returns True if feature is changed in the autoconfig layer.
+ """
+
+ root_conf = feat.get_root_configuration()
+ conf = root_conf.get_configuration_by_index(-1)
+
+ def check(node):
+ if isinstance(node, api.Data) and node.fqr == feat.fqr:
+ return True
+ for obj in node._objects():
+ if check(obj):
+ return True
+
+ if check(conf):
+ return True
+ else:
+ return False
+
+def changed_on_layer(feat, layer):
+ """
+ Returns True if feature is changed in the given layer.
+ """
+ try:
+ return give_changed_layers(feat)[layer]
+ except IndexError, e:
+ logger.warning("Given layer is not found: %s" % (layer))
+ return False
+
+def changed_on_layers(feat, findex, tindex):
+ """
+ Returns True if feature is changed in layer of given range.
+ """
+ layers = give_changed_layers(feat)
+
+ if findex == tindex:
+ return changed_on_layer(feat, findex)
+
+ for i in range(findex, tindex):
+ if i > len(layers):
+ continue
+ if layers != None and layers[i] != None and layers[i]:
+ return True
+ return False
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/shortcuts_conversion.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/shortcuts_conversion.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+
+def get_fixed_target_path(feature, setting):
+ type_ref = setting + '_type'
+ type = feature.get_feature(type_ref)
+ type_value = type.get_value()
+ ret = ""
+ if type_value == '1':
+ None
+ elif type_value == '2':
+ icon = feature.get_feature(setting + '_icon')
+ if icon != None:
+ ret = get_fixed_icon_target(icon)
+ else:
+ None
+
+ return ret
+
+def get_fixed_icon_target(icon):
+ targetPath = icon.get_feature('targetPath').get_value()
+ localPath = icon.get_feature('localPath').get_value()
+ target = get_target_without_extension(targetPath)
+ extension = get_correct_extension(localPath)
+ fixed = ""
+ if extension != None:
+ if len(target) > 0 and len(extension) > 0:
+ fixed = target + extension
+ return fixed
+
+def get_target_without_extension(targetPath):
+ (target,_) = os.path.splitext(targetPath)
+ return target
+
+def get_correct_extension(localPath):
+
+ if localPath != None:
+ (_,extension) = os.path.splitext(localPath)
+ if extension == '.bmp':
+ return '.mbm'
+ elif extension == '.svg':
+ return '.mif'
+ else:
+ return extension
+ else:
+ return None
+
+def get_shortcut_string(feature, setting):
+ type_ref = setting + '_type'
+ type_value = feature.get_feature(type_ref).get_value()
+ ret = ""
+ if type_value == '1':
+ app_ref = setting + '_app'
+ application = feature.get_feature(app_ref).get_value()
+ ret = application
+ elif type_value == '2':
+ url = feature.get_feature(setting+'_URL').get_value()
+ title = feature.get_feature(setting+'_title').get_value()
+
+ if title == None:
+ title = ""
+ else:
+ title = 'customtitle=' + title
+
+ icon = feature.get_feature(setting + '_icon')
+ image_path = icon.get_feature('targetPath').get_value()
+
+ icon_str = ""
+
+ if image_path != None and image_path != "":
+ icon_str = 'iconmifpath='
+ if image_path.endswith('.mif'): index = '16384'
+ else: index = '0'
+ icon_str = icon_str + image_path + ';' + index + '&'
+
+ ret = url + '?custom?' + icon_str + title
+ return ret
+
+#print get_shortcut_string('1', '2', '3')
+#http://www.nokia2.com?custom?iconmifpath=Z:\\resource\\apps\\icon2.mbm;1&customtitle=Nokia2
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH, '../../..')
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ String 1
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/implml/test1.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/implml/test1.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+ {% changed_on_layer( @{StringFeatureTest.Value1}, -1) %} configures result1 = True
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer2/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer2/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+ String 2
+ String 2
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer2/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer2/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer3/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer3/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+ String 3
+ String 3
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer3/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer3/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer4/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer4/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+ String 4
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer4/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer4/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer5/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer5/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+ String 5
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer5/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer5/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/ctd/confml/CTD_commsdat.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/ctd/confml/CTD_commsdat.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,460 @@
+
+
+
+
+
+
+ Selection for A-GPS access point
+
+
+
+
+
+
+
+ Selection for MMS access point
+
+
+
+
+
+
+ Selection for Browser access point
+
+
+
+
+
+
+ Setting for the default Destination Network
+
+
+
+
+
+
+
+ Selection for web feeds autoupdate access point
+
+
+
+
+
+
+ Selection for Email access point
+
+
+
+
+
+
+ Selection for Email access point
+
+
+
+
+
+
+
+ Selection for Email access point
+
+
+
+
+
+
+
+ Selection for Email access point
+
+
+
+
+
+
+ Selection for Email access point
+
+
+
+
+
+
+ Selection for Email access point
+
+
+
+
+
+
+ GPRS connection method (CM) definitions
+
+
+ The access point name that is visible to the user.
+
+
+ The access point name for this GPRS connection
+
+
+ Define the destination network that the access point will be added to. Can be left empty.
+
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Addressing that the network uses.
+
+
+
+
+ User name
+
+
+ Prompt password at connection time.
+
+
+
+
+ Password.
+
+
+ Password authentication method.
+
+
+
+
+ Access point homepage in URL format.
+
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+
+
+
+
+ WLAN connection method (CM) definitions
+
+
+ The access point name that is visible to the user.
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Service set identifier (SSID) of the primary WLAN network.
+
+
+ Define the destination network that the access point will be added to. Can be left empty.
+
+
+
+
+
+ Access point homepage in URL format.
+
+
+ Determines the network infrastructure.
+ If there is a WLAN access point in the network then this should be Infrastructure.
+
+
+
+
+
+ Defines whether the SSID should be actively scanned.
+ This is needed if the SSID is hidden (not broadcasted by the AP)
+
+
+
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+
+ 802.11 Channel ID (1-14). Used only when connecting/setting up adhoc network.
+
+
+
+ Security mode of the WLAN network.
+
+
+
+
+
+
+
+ Index of default WEP key. Used only when security mode is WEP.
+
+
+
+
+
+
+ WEP authentication mode. Only used when security mode is WEP.
+
+
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+
+ Specifies that when the security mode is WPA or WPA2 if the PSK mode is enabled.
+ If this is off then EAP mode is used and the list of EAPs needs to be defined.
+
+
+
+
+ The length of the specified pre-shared key (in WPA pre-shared key field)
+
+
+ WPA/WPA2 pre-shared key in plain text. ASCII character set values between 32-126 must be used. Minimum length is 8 characters and maximum 63.
+ You need to also define the WPA pre-shared key length field accordingly
+
+
+
+ Eap Key 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Eap Key 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Eap Key 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Eap Key 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Eap Key 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Eap Key 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Eap Key 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ConfirmFirst
+ IPv4
+ No
+ Normal
+
+
+
+
+
+
+ ConfirmFirst
+ Infrastructure
+ Open
+ 0
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/ctd/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/ctd/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/confml/ap.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/confml/ap.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+ Full 1
+
+
+ Full 2
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/confml/commsdatcreator.confml
Binary file configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/confml/commsdatcreator.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/confml/testdata.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/confml/testdata.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ image_conf_imakerapi.mk
+
+
+ 0
+ V .50.2009.04.0113 RND
+ myProduct
+ myProduct
+
+
+
+ 5
+ 25
+ 7
+ 5
+ 10
+ 2
+ 5
+ 10
+ 8
+
+
+ String 1
+ String 2
+ x
+ x
+ x
+ x
+ x
+ x
+
+
+ <ударениÑ>
+ <ελληνικά>カタカナελληνικά>
+ ударениÑ>
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/implml/accesspoint_id_counter.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/implml/accesspoint_id_counter.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+ True configures APIDCTest.FullSequence.StringSubSetting = {% apid( @{APs}, @{DNs} ) %}
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/confml/data.confml
Binary file configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/confml/data.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_accesspoint_id_counter.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_accesspoint_id_counter.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,125 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import pkg_resources
+import re
+
+import __init__
+
+from ruleplugin import ruleml, relations
+from cone.public import api, exceptions
+from ruleplugin.evals import accesspoint_id_counter
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestAPIDC(unittest.TestCase):
+ def test_get_ApDnContainer(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals('Internet', container.get_all_dns()[0].get_name())
+ self.assertEquals('1', container.get_all_dns()[0].get_id())
+ self.assertEquals(['IAP11', 'IAP12', 'IAP13', None, None, None, None, None, None, None], container.get_all_dns()[0].get_iaps())
+
+ self.assertEquals('MMS', container.get_all_dns()[1].get_name())
+ self.assertEquals('2', container.get_all_dns()[1].get_id())
+ self.assertEquals(['IAP21', 'IAP22', 'IAP23', 'IAP13', None, None, None, None, None, None], container.get_all_dns()[1].get_iaps())
+
+ self.assertEquals('Operator', container.get_all_dns()[2].get_name())
+ self.assertEquals('3', container.get_all_dns()[2].get_id())
+ self.assertEquals(['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None], container.get_all_dns()[2].get_iaps())
+
+ self.assertEquals('IAP11', container.get_all_aps()[0].get_name())
+ self.assertEquals('1', container.get_all_aps()[0].get_id())
+
+ def test_get_apid_by_apname(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals('1', container.get_apid_by_apname('IAP11'))
+ self.assertEquals('2', container.get_apid_by_apname('IAP12'))
+ self.assertEquals('7', container.get_apid_by_apname('IAP13'))
+
+ def test_get_dnid_by_dnname(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals('1', container.get_dnid_by_dnname('Internet'))
+ self.assertEquals('2', container.get_dnid_by_dnname('MMS'))
+ self.assertEquals('3', container.get_dnid_by_dnname('Operator'))
+
+
+ def test_get_apid_by_dnname_and_apname(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals('2', container.get_apid_by_dnname_and_apname('Internet', 'IAP12'))
+
+ def test_calc_ap_ids(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals('9', container.get_all_aps()[6].get_id())
+
+ def test_all_in_array(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals(container.get_all_in_array(), [['Internet', '1', ['IAP11', 'IAP12', 'IAP13', None, None, None, None, None, None, None], ['1', '2', '7', None, None, None, None, None, None, None], ['1', '2', '3', None, None, None, None, None, None, None]], ['MMS', '2', ['IAP21', 'IAP22', 'IAP23', 'IAP13', None, None, None, None, None, None], ['4', '8', '6', '7', None, None, None, None, None, None], ['4', '5', '6', '3', None, None, None, None, None, None]], ['Operator', '3', ['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None], [None, None, '9', None, None, None, None, None, None, None], [None, None, '7', None, None, None, None, None, None, None]]])
+
+ def test_get_next_free_id(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals("4", accesspoint_id_counter._get_next_free_id_(container.get_all_dns()))
+ self.assertEquals("10", accesspoint_id_counter._get_next_free_id_(container.get_all_aps()))
+
+ def test_get_apindex_by_apname(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+ self.assertEquals("4", container.get_apindex_by_apname("IAP21"))
+ self.assertEquals("1", container.get_apindex_by_apname("IAP11"))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_layer_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_layer_utils.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,92 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import pkg_resources
+import re
+import logging
+
+import __init__
+
+from ruleplugin import ruleml, relations
+from cone.public import api, exceptions
+from ruleplugin.evals import layer_utils
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+#logger = logging.getLogger("cone.ruleplugin.evals.layer_utils")
+#logger.setLevel(logging.DEBUG)
+#ch = logging.StreamHandler()
+#ch.setLevel(logging.DEBUG)
+#logger.addHandler(ch)
+
+class TestLayerUtils(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_give_changed_layers(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ self.assertEquals(layer_utils.give_changed_layers(dview.get_feature("StringFeatureTest.Value1")), [True, True, True, True, True])
+ self.assertEquals(layer_utils.give_changed_layers(dview.get_feature("StringFeatureTest.Value2")), [False, True, True, False, False])
+
+ def test_changed_on_last_layer(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ self.assertTrue(layer_utils.changed_on_last_layer(dview.get_feature("StringFeatureTest.Value1")))
+ self.assertFalse(layer_utils.changed_on_last_layer(dview.get_feature("StringFeatureTest.Value2")))
+
+ def test_changed_on_layer(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),-1))
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),0))
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),1))
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),2))
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),3))
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),4))
+ self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),5))
+ self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),-1))
+ self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),0))
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),1))
+ self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),2))
+ self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),3))
+ self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),4))
+ self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),5))
+
+ def test_changed_on_layers(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+ config = project.get_configuration('root.confml')
+ dview = config.get_default_view()
+
+ self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),0,4))
+ self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),2,3))
+ self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),2,2))
+ self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),1,7))
+ self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),8,9))
+ self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),0,1))
+ self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),1,5))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/relations.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/relations.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,406 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+'''
+implementation for ruleml relations.
+'''
+import os
+import StringIO
+import logging
+import operator as ops
+import re
+import sys, traceback
+
+log = logging.getLogger('cone.ruleplugin.relations')
+
+from cone.public import api, rules, utils, exceptions, plugin
+
+class RelationFactory(api.FactoryBase):
+ @ classmethod
+ def get_relation_by_name(cls, relation_name):
+ """
+ Get the class name by file extension.
+ """
+ try:
+ return rules.RELATIONS.get(relation_name)
+ except KeyError:
+ raise exceptions.NotSupportedException("No Relation class found for name %s" % relation_name)
+
+ @ classmethod
+ def get_relations(cls, configuration, relation):
+ try:
+ relations = []
+ (left_expression,relation_name,right_expression) = parse_rule(relation)
+ relation = cls.get_relation_by_name(relation_name)(configuration, left_expression, right_expression)
+ relations.append(relation)
+ propagated_relations = cls.get_relations(configuration, right_expression)
+ if propagated_relations:
+ for relation in propagated_relations:
+ relations.append(relation)
+ return relations
+ except exceptions.ParseError:
+ return None
+
+
+class ConfigurationContext(rules.DefaultContext):
+
+ def __init__(self, data):
+ rules.DefaultContext.__init__(self, data)
+
+ # A note on the callback variables that follow:
+ # in order to collect rule execution results for the
+ # generation report, a callback system is implemented in
+ # ConfigurationContext. It all boils down to ConfigureRelation
+ # using configure_expression_result_callback to catch the result
+ # in its execute() method. The ConfigurationContext just works as
+ # a "callback hub" because a reference to the context is available
+ # in all expression evaluations.
+
+ # Callback called with a plugin.RelationExecutionResult object
+ # when a ConfigureExpression has been evaluated
+ self.configure_expression_result_callback = None
+
+ # Callback called with the setting reference when a setting is dereferenced
+ # as a terminal expression
+ self.ref_terminal_callback = None
+
+ # Callback called with the setting reference when a setting is dereferenced
+ # inside an EvalExpression
+ self.ref_eval_callback = None
+
+ # Callback called with the setting reference when the value of a setting
+ # is set inside a SetExpression
+ self.ref_set_callback = None
+
+ def handle_terminal(self, expression):
+ try:
+ value = self.data.get_default_view().get_feature(expression).get_value()
+
+ # Got a valid ref, call the callback
+ if self.ref_terminal_callback:
+ self.ref_terminal_callback(expression)
+
+ return value
+ except exceptions.NotFound,e:
+ """ return the expression itself if it is not a fearef """
+ #print "handle_terminal constant %s" % (expression)
+ try:
+ return eval(expression)
+ except (NameError,SyntaxError), e:
+ return expression
+
+ def eval(self, ast, expression, value):
+ #print "expression %s = %s" % (expression,value)
+ pass
+
+class ConfigurationBaseRelation(rules.BaseRelation):
+ def __init__(self, data, left, right):
+ self.context = ConfigurationContext(data)
+ super(ConfigurationBaseRelation, self).__init__(data, left, right)
+
+class RequireRelation(ConfigurationBaseRelation):
+ KEY = 'requires'
+ def __init__(self, data, left, right):
+ super(RequireRelation, self).__init__(data, left, right)
+ self.context = ConfigurationContext(data)
+
+class ConfigureRelation(ConfigurationBaseRelation):
+ KEY = 'configures'
+ def __init__(self, data, left, right):
+ self.context = ConfigurationContext(data)
+ super(ConfigureRelation, self).__init__(data, left, right)
+
+ # A plugin.RelationExecutionResult object is stored here
+ self._execution_result = None
+
+
+ def execute(self):
+ self._execution_result = None
+ exec_results = []
+
+ # Call BaseRelation.execute() and catch any ConfigureExpression result objects
+ self.context.configure_expression_result_callback = lambda result: exec_results.append(result)
+ result = rules.BaseRelation.execute(self)
+ self.context.configure_expression_result_callback = None
+
+ if len(exec_results) > 0:
+ # There should be only one ConfigureExpression inside a ConfigureRelation
+ if len(exec_results) > 1:
+ log.warning("Execution of ConfigureRelation returned more than one result, ignoring all except the first")
+ self._execution_result = exec_results[0]
+
+ return result
+
+ def get_execution_result(self):
+ """
+ Return the execution result from the most recent call to execute().
+ """
+ return self._execution_result
+
+def handle_configure(self, left, right):
+ if left and right:
+ return True
+ elif not left:
+ return True
+ return False
+
+def handle_set(self, left, right):
+ left.set_value(right)
+
+def handle_filenamejoin(self, left, right):
+ def extract_dirname(path):
+ """Extract directory name (will always contain a trailing slash or backslash)"""
+ pos = max(path.rfind('/'), path.rfind('\\'))
+ if pos == -1: return path + '/'
+ else: return path[:pos + 1]
+
+ def extract_filename(path):
+ pos = max(path.rfind('/'), path.rfind('\\'))
+ if pos == -1: return path
+ else: return path[pos + 1:]
+
+ return extract_dirname(left) + extract_filename(right)
+
+def handle_plus(self, left, right):
+ return left + right
+
+def handle_minus(self, left, right):
+ return left - right
+
+def handle_multiply(self, left, right):
+ return left * right
+
+def handle_divide(self, left, right):
+ return left / right
+
+class ConfigureExpression(rules.TwoOperatorExpression):
+ PRECEDENCE = rules.PRECEDENCES['RELATION_OPERATORS']
+ KEY = 'configures'
+ OP = handle_configure
+
+ def eval(self, context):
+ input_refs = []
+ affected_refs = []
+
+ # Evaluate the left-hand side expression, catching refs for the result
+ try:
+ context.ref_terminal_callback = lambda ref: input_refs.append(ref)
+ context.ref_eval_callback = lambda ref: input_refs.append(ref)
+ evaluated_left = self.left.eval(context)
+ finally:
+ context.ref_terminal_callback = None
+ context.ref_eval_callback = None
+
+ if evaluated_left:
+ # If left evaluated to True, evaluate the right-hand side and
+ # catch refs from SetExpression evaluations
+ try:
+ context.ref_set_callback = lambda ref: affected_refs.append(ref)
+ self.value = self.right.eval(context)
+ finally:
+ context.ref_set_callback = None
+ else:
+ self.value = True
+
+ if not self.value:
+ left_keys = []
+ for ref in self.ast.extract_refs(str(self.left)):
+ for key in context.get_keys(ref):
+ left_keys.append(key)
+
+ for key in left_keys:
+ self.ast.add_error(key, { 'error_string' : 'CONFIGURES right side value is "False"',
+ 'left_key' : key,
+ 'rule' : self.ast.expression
+ })
+
+ # Return a RelationExecutionResult if necessary
+ if input_refs or affected_refs:
+ if context.configure_expression_result_callback:
+ result = plugin.RelationExecutionResult(utils.distinct_array(input_refs),
+ utils.distinct_array(affected_refs))
+ context.configure_expression_result_callback(result)
+
+ return self.value
+
+class MultiplyExpression(rules.TwoOperatorExpression):
+ expression = "multiply_operation"
+ PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
+ KEY= '*'
+ OP = handle_multiply
+
+class DivideExpression(rules.TwoOperatorExpression):
+ expression = "divide_operation"
+ PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
+ KEY= '/'
+ OP = handle_divide
+
+class PlusExpression(rules.TwoOperatorExpression):
+ expression = "plus_operation"
+ PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
+ KEY= '+'
+ OP = handle_plus
+
+class MinusExpression(rules.TwoOperatorExpression):
+ expression = "minus_operation"
+ PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
+ KEY= '-'
+ OP = handle_minus
+
+class EvalExpression(rules.OneParamExpression):
+ expression = "__eval__"
+ PRECEDENCE = rules.PRECEDENCES['PREFIX_OPERATORS']
+ KEY = '__eval__'
+
+ def __init__(self, ast, expression):
+ super(rules.OneParamExpression, self).__init__(ast)
+ self.expression = expression
+ self._str_to_eval = eval(expression.expression)
+ #self.default_view = default_view
+
+ def extract_refs(self):
+ result = []
+ result.extend(utils.extract_delimited_tokens(self._str_to_eval, delimiters=('${', '}')))
+ result.extend(utils.extract_delimited_tokens(self._str_to_eval, delimiters=('@{', '}')))
+ return result
+
+ def eval(self, context):
+ # Using the configuration to pass the eval globals dictionary to here,
+ # since there isn't any easy way to do this more elegantly
+ globals_and_locals = {}
+ if hasattr(context.data, '_eval_expression_globals_dict'):
+ globals_and_locals = context.data._eval_expression_globals_dict
+
+ str_to_eval = self._str_to_eval
+
+ def expand_feature_ref(ref, index):
+ var_name = "__fea_%05d" % index
+ globals_and_locals[var_name] = context.data.get_default_view().get_feature(ref)
+ if context.ref_eval_callback:
+ context.ref_eval_callback(ref)
+ return var_name
+ def expand_value_ref(ref, index):
+ var_name = "__feaval_%05d" % index
+ globals_and_locals[var_name] = context.data.get_default_view().get_feature(ref).get_value()
+ if context.ref_eval_callback:
+ context.ref_eval_callback(ref)
+ return var_name
+
+ str_to_eval = utils.expand_delimited_tokens(str_to_eval, expand_feature_ref, delimiters=('@{', '}'))
+ str_to_eval = utils.expand_delimited_tokens(str_to_eval, expand_value_ref, delimiters=('${', '}'))
+
+ # Strip leading and trailing whitespace to avoid indentation problems
+ str_to_eval = str_to_eval.strip()
+
+ ret = None
+
+ try:
+ ret = eval(str_to_eval, globals_and_locals)
+ return ret
+ except SyntaxError, e:
+ logging.getLogger('cone.ruleml').warning("Invalid syntax in eval: %s" % (str_to_eval) )
+ self.ast.add_error(self.expression, { 'error_string' : 'Invalid syntax in eval', 'str_to_eval' : str_to_eval, 'rule' : self.ast.expression })
+ except Exception, e:
+ logging.getLogger('cone.ruleml').warning("Execution failed for eval: %s %s: %s" % (str_to_eval, type(e), e) )
+ self.ast.add_error(self.expression, { 'error_string' : 'Execution failed for eval', 'str_to_eval' : str_to_eval, 'rule' : self.ast.expression })
+
+rules.OPERATORS[EvalExpression.KEY] = EvalExpression
+
+class FilenamejoinExpression(rules.TwoOperatorExpression):
+ expression = "filenamejoin"
+ PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
+ KEY = 'filenamejoin'
+ OP = handle_filenamejoin
+
+rules.OPERATORS[FilenamejoinExpression.KEY] = FilenamejoinExpression
+
+class SetExpression(rules.TwoOperatorExpression):
+ PRECEDENCE = rules.PRECEDENCES['SET_OPERATORS']
+ KEY= '='
+ OP = handle_set
+
+ def eval(self, context):
+ try:
+ variable = context.data.get_default_view().get_feature(self.left.expression)
+ value = self.right.eval(context)
+ variable.set_value(value)
+ logging.getLogger('cone.ruleml').info("Set %r = %r from %r" % (self.left.expression, value, self.right.expression) )
+ if context.ref_set_callback:
+ context.ref_set_callback(self.left.expression)
+ return True
+ except exceptions.NotFound,e:
+ self.ast.add_error(self.left.expression, { 'error_string' : 'Setting value failed, because of %s' % e,
+ 'left_key' : self.left.expression,
+ 'rule' : self.ast.expression})
+ return False
+
+_relations_and_operators_backup = None
+
+def register():
+ """
+ Register the relations and operators to ConE rules.
+ """
+ global _relations_and_operators_backup
+ if _relations_and_operators_backup is None:
+ # Create the backup copies of the dictionaries
+ rels_backup = rules.RELATIONS.copy()
+ ops_backup = rules.OPERATORS.copy()
+ assert rels_backup is not rules.RELATIONS
+ assert ops_backup is not rules.OPERATORS
+ _relations_and_operators_backup = (rels_backup, ops_backup)
+
+ # Register relations and operators to rules
+ rules.RELATIONS[RequireRelation.KEY] = RequireRelation
+ rules.RELATIONS[ConfigureRelation.KEY] = ConfigureRelation
+ rules.OPERATORS[ConfigureExpression.KEY] = ConfigureExpression
+ rules.OPERATORS[PlusExpression.KEY] = PlusExpression
+ rules.OPERATORS[SetExpression.KEY] = SetExpression
+ rules.OPERATORS[MinusExpression.KEY] = MinusExpression
+ rules.OPERATORS[MultiplyExpression.KEY] = MultiplyExpression
+ rules.OPERATORS[DivideExpression.KEY] = DivideExpression
+
+def unregister():
+ """
+ Undo the changes made by a call to register().
+ """
+ global _relations_and_operators_backup
+ if _relations_and_operators_backup is not None:
+ rules.RELATIONS = _relations_and_operators_backup[0]
+ rules.OPERATORS = _relations_and_operators_backup[1]
+ _relations_and_operators_backup = None
+
+def parse_rule(rulestring):
+ """
+ Divide the given rule string into (left side, relation, right side) components.
+ @return: Triple (left side, relation, right side)
+ """
+ left_expression = ''
+ relation_name = None
+ right_expression = ''
+ for token in rules.get_tokens(rulestring):
+ if relation_name == None:
+ if token in rules.RELATIONS.keys():
+ relation_name = token
+ else:
+ left_expression += ' ' + token
+ else:
+ right_expression += ' ' + token
+
+ if relation_name == None:
+ raise exceptions.ParseError('invalid rule definition %s' % rulestring)
+
+ return (left_expression,relation_name,right_expression)
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/ruleml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/ruleml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,241 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+A plugin implementation for rule generation.
+'''
+
+
+import os
+import sys
+import logging
+import shutil
+
+import __init__
+import re
+
+from ruleplugin import relations
+from cone.public import exceptions,plugin,utils,api,rules
+
+class RuleImpl(plugin.ImplBase):
+ """
+ MakeImpl plugin finds feature references that are configured in a .ruleml file
+ and generate a rule from them
+ """
+ IMPL_TYPE_ID = 'ruleml'
+ DEFAULT_INVOCATION_PHASE = 'pre'
+
+ def __init__(self, ref, configuration, relation_container):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.logger = logging.getLogger('cone.ruleml(%s)' % self.ref)
+ self.relation_container = relation_container
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ return []
+
+ def generate(self, context=None):
+ self.logger.info("Generating rules from %s" % self.ref)
+ relation_container = self.get_relation_container()
+ relation_container.context = context
+ return relation_container.execute()
+
+ def has_tag(self, tags, policy=None):
+ # RuleML should always be executed, regardless of the tags
+ return True
+
+ def get_relation_container(self):
+ return self.relation_container
+
+class RulemlRelationContainer(plugin.RelationContainer):
+ """
+ Relation container for RuleML rules.
+
+ Basically this is a wrapper for rules.RelationContainer that adapts
+ it to the interface of plugin.RelationContainer.
+ """
+ def __init__(self, configuration, source, rule_list, eval_globals):
+ plugin.RelationContainer.__init__(self, configuration, source=source)
+ self.logger = logging.getLogger('cone.ruleml_relation_container(%s)' % self.source)
+ self.configuration = configuration
+ self.relation_container = rules.RelationContainerImpl()
+ self.eval_globals = eval_globals
+ self.context = None
+ for rule in rule_list:
+ self.relation_container.add_relation(rule)
+
+ def execute(self):
+ results = []
+
+ # Create the autoconfig if not done already
+ plugin.get_autoconfig(self.configuration)
+
+ # Register relations etc. to the rule engine.
+ # Due to unit test issues the relations are not registered
+ # in the relations module, but only for the duration of
+ # rule parsing and execution
+ relations.register()
+ try:
+ # Using the configuration to pass the eval globals dict to the
+ # eval expression. The configuration only contains the globals
+ # dict for the duration of the rule execution, so hopefully this
+ # shouldn't mess anything up
+ self._set_builtin_eval_globals()
+ self.configuration._eval_expression_globals_dict = self.eval_globals
+ for i, rel in enumerate(self.relation_container):
+ index = i + 1
+
+ # Execute
+ self._execute_relation_and_log_error(rel, self.source, index)
+
+ # Collect execution result if supported
+ if hasattr(rel, 'get_execution_result'):
+ result = rel.get_execution_result()
+ if isinstance(result, plugin.RelationExecutionResult):
+ result.source = self.source
+ result.index = index
+ results.append(result)
+
+ del self.configuration._eval_expression_globals_dict
+
+ if self.relation_container.has_errors():
+ for error in self.relation_container.get_errors():
+ self.logger.error(error)
+
+ if self.context:
+ self.context.results += results
+ return results
+ finally:
+ relations.unregister()
+
+ def get_relation_count(self):
+ return len(self.relation_container)
+
+ def _set_builtin_eval_globals(self):
+ """
+ Add built-in attributes into the eval globals dictionary.
+ """
+ class RuleBuiltinsModule(object):
+ pass
+
+ builtins = RuleBuiltinsModule()
+ builtins.configuration = self.configuration
+
+ self.eval_globals['ruleml'] = builtins
+
+class RuleImplReaderBase(plugin.ReaderBase):
+ NAMESPACE = None # Used as a base class, so should have no namespace
+ FILE_EXTENSIONS = ['ruleml']
+
+ def __init__(self, resource_ref, configuration):
+ self.resource_ref = resource_ref
+ self.configuration = configuration
+ self.logger = logging.getLogger('cone.ruleml(%s)' % self.resource_ref)
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = cls(resource_ref, configuration)
+
+ # Register relations etc. to the rule engine.
+ # Due to unit test issues the relations are not registered
+ # in the relations module, but only for the duration of
+ # rule parsing and execution
+ relations.register()
+ try:
+ rules = reader.parse_rules(etree)
+ eval_globals = reader.parse_eval_globals(etree)
+
+ relation_container = RulemlRelationContainer(
+ configuration = configuration,
+ source = resource_ref,
+ rule_list = rules,
+ eval_globals = eval_globals)
+
+ impl = RuleImpl(resource_ref, configuration, relation_container)
+ finally:
+ relations.unregister()
+
+ return impl
+
+class RuleImplReader1(RuleImplReaderBase):
+ NAMESPACE = 'http://www.s60.com/xml/ruleml/1'
+
+ def __init__(self, resource_ref, configuration):
+ RuleImplReaderBase.__init__(self, resource_ref, configuration)
+
+ def parse_rules(self, etree):
+ rules = []
+ for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
+ rules.extend(relations.RelationFactory.get_relations(self.configuration, elem.text))
+ return rules
+
+ def parse_eval_globals(self, etree):
+ return {}
+
+class RuleImplReader2(RuleImplReaderBase):
+ NAMESPACE = 'http://www.s60.com/xml/ruleml/2'
+
+ def __init__(self, resource_ref, configuration):
+ RuleImplReaderBase.__init__(self, resource_ref, configuration)
+
+ def parse_rules(self, etree):
+ rules = []
+ for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
+ rules.extend(relations.RelationFactory.get_relations(self.configuration, self._replace_eval_blocks(elem.text)))
+ return rules
+
+ def parse_eval_globals(self, etree):
+ eval_globals = {}
+ for elem in etree.getiterator("{%s}eval_globals" % self.NAMESPACE):
+ text = ""
+ if elem.get('file') != None:
+ self._read_eval_globals_from_file(elem.get('file'), eval_globals)
+ else:
+ try:
+ # Strip surrounding whitespace, otherwise there might be Python
+ # indentation errors
+ text = elem.text.strip()
+ exec(text, eval_globals)
+ except Exception, e:
+ self.logger.warning('Failed to evaluate eval_globals block, exception: %s' % (e))
+ return eval_globals
+
+ def _read_eval_globals_from_file(self, relative_path, eval_globals):
+ # Get the actual path (relative to the current implementation file)
+ base_path = os.path.dirname(self.resource_ref)
+ pyfile_path = os.path.normpath(os.path.join(base_path, relative_path)).replace('\\', '/')
+ # Read the data and execute
+ try:
+ resource = None
+ resource = self.configuration.get_resource(pyfile_path)
+ text = resource.read()
+ exec(text.replace('\r', ''), eval_globals)
+ except Exception, e:
+ self.logger.warning('Cannot import eval file: %s. Exception: %s' % (pyfile_path, e))
+ finally:
+ if resource is not None: resource.close()
+
+
+ @classmethod
+ def _replace_eval_blocks(cls, code):
+ return utils.expand_delimited_tokens(
+ string = code,
+ expander_func = lambda ref, index: '__eval__ %r' % ref,
+ delimiters =('{%', '%}'))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/confml/testdata.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/confml/testdata.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/implml/terminalexpression.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/implml/terminalexpression.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+ True configures EvalTest.StringLenResult = 22
+ True configures EvalTest.StringLenResult = {% SOME_VALUE %}
+ SOME_VALUE = 12345
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/confml/invalid_python_eval.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/confml/invalid_python_eval.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/implml/invalid_python_eval.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/implml/invalid_python_eval.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+ True configures EvalTest2.StringResult = {% -> this is invalid python code %}
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/confml/invalid_python_eval.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/confml/invalid_python_eval.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/implml/invalid_python_eval.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/implml/invalid_python_eval.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+ True configures EvalTest3.StringResult = 22
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/implml/scripts/test_eval.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/implml/scripts/test_eval.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+this is some other invalid python code
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/confml/invalid_python_eval.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/confml/invalid_python_eval.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/implml/invalid_python_eval.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/implml/invalid_python_eval.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+ True configures EvalTest4.StringResult = 22
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/confml/invalid_python_eval.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/confml/invalid_python_eval.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/implml/invalid_python_eval.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/implml/invalid_python_eval.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+ True configures EvalTest5.StringResult = {% 7/0 %}
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/implml/scripts/test_eval.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/implml/scripts/test_eval.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+this is some other invalid python code
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/confml/invalid_python_eval.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/confml/invalid_python_eval.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/implml/invalid_python_eval.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/implml/invalid_python_eval.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+ True configures EvalTest6.StringResult = Invalid.setting
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/.project
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/.project Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+
+
+ config_project
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerBuilder
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerNature
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/confml/actionpriorities.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/confml/actionpriorities.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+ 25
+ 7
+ 5
+ 10
+ 2
+ 6
+ 10
+ 9
+ Hello
+ World
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/implml/gsm.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/implml/gsm.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+ operations.minus == 5 configures operations.minus = operations.minus1 - operations.minus2
+ operations.minus1 == 25 configures operations.minus1 = operations.minus3 * operations.minus2
+ operations.minus4 == 10 configures operations.minus4 = operations.minus4 / operations.minus5
+ operations.minus6 == 6 configures operations.minus6 = operations.minus7 + operations.minus8
+ operations.string1 == 'Hello' configures operations.string1 = operations.string1 + operations.string2
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/rule/config_project/platforms/customsw/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/arithmetic.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/arithmetic.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+ 20
+
+ 5
+ 20
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/commsdatcreator.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/commsdatcreator.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1935 @@
+
+
+ Used to configure whether CommsDat generation from these settings is enabled.
+
+ This is the master switch that determines whether CommsDat is created in the first boot
+ of the device based on Configuration Tool output. Set this to Yes if you are creating variant
+ and need to configure anything under Default CommsDat settings.
+
+
+
+
+ Read-only flag that indicates the CommsDatCreator start-up status in runtime.
+
+
+
+
+ Global networking related settings not tied to individual connection methods.
+
+
+
+ GPRS attach mode (attach when needed/when available).
+
+
+
+
+
+
+ Default GPRS access point. Used when the phone is used as a modem for a PC.
+ The corresponding UI setting is Connection-Packet data-Access point.
+
+
+
+
+ Default icon for destination networks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default priority for LAN bearer type.
+
+
+
+
+ Default priority for WLAN bearer type.
+
+
+
+
+ Default priority for PAN bearer type.
+
+
+
+
+ Default priority for outgoing GPRS bearer type.
+
+
+
+
+ Default priority for incoming GPRS bearer type.
+
+
+
+
+ Default priority for CDMA 2000 bearer type.
+
+
+
+
+ Default priority for outgoing dial bearer type.
+
+
+
+
+ Default priority for incoming dial bearer type.
+
+
+
+
+ Default priority for VPN bearer type.
+
+
+
+
+ Default priority for MIP bearer type.
+
+
+
+
+ Default UI priority of LAN connection.
+
+
+
+
+ Default UI priority for WLAN bearer type.
+
+
+
+
+ Default UI priority for PAN bearer type.
+
+
+
+
+ Default UI priority for outgoing GPRS bearer type.
+
+
+
+
+ Default UI priority for incoming GPRS bearer type.
+
+
+
+
+ Default UI priority for CDMA 2000 bearer type.
+
+
+
+
+ Default UI priority for outgoing dial bearer type.
+
+
+
+
+ Default UI priority for incoming dial bearer type.
+
+
+
+
+ Default UI priority for VPN bearer type.
+
+
+
+
+ Default UI priority for MIP bearer type.
+
+
+
+
+ Specifies how the applications' default connection is specified.
+
+
+
+
+
+
+
+
+ The name of the default connection (connection method or destination network).
+ Default connection type parameter needs to be set accordingly.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when session has closed. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when socket has closed. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ How often WLAN networks are scanned when idle.
+
+
+
+
+
+
+
+
+ Defines whether default values are being used for the advanced WLAN settings (recommended).
+
+
+
+
+ Defines how many times packets bigger than RTS Threshold are been resent.
+
+
+ Defines how many times packets smaller than RTS Threshold are been resent.
+
+
+ Minimum size of a packet for which CTS/RTS handshake has been used.
+
+
+ Transmission power level in use. In mWs. 4, 10 or 100 mW.
+
+
+
+
+
+ Defines whether the CCX radio measurements are allowed.
+
+
+
+
+ Defines whether power saving methods are active. Disabling WLAN
+ power save might increase interoperability but will dramatically shorten battery life.
+
+
+
+
+
+ GPRS connection method (CM) definitions
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Addressing that the network uses.
+
+
+
+
+ The access point name for this GPRS connection
+
+
+ User name
+
+
+ Prompt password at connection time.
+
+
+
+
+ Password.
+
+
+ Password authentication method.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method. In URL format.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Allow EDGE usage.
+
+
+
+
+ Specifies the service provider type. Used when filtering connection methods for certain purpose.
+
+
+
+
+
+
+
+ WLAN connection method (CM) definitions
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Service set identifier (SSID) of the primary WLAN network.
+
+
+ Start page of the connection method. In URL format.
+
+
+ Determines the network infrastructure.
+ If there is a WLAN access point in the network then this should be Infrastructure.
+
+
+
+
+ Security mode of the WLAN network.
+
+
+
+
+
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ The gateway IP address.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Network mask. Typically allocated automatically in which case this should be empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Defines whether the SSID should be actively scanned.
+ This is needed if the SSID is hidden (not broadcasted by the AP)
+
+
+
+
+
+ 802.11 Channel ID (1-14). Used only when connecting/setting up adhoc network.
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Index of default WEP key. Used only when security mode is WEP.
+
+
+
+
+
+
+ WEP authentication mode. Only used when security mode is WEP.
+
+
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WPA/WPA2 pre-shared key in plain text. ASCII character set values between 32-126 must be used. Minimum length is 8 characters and maximum 63.
+ You need to also define the WPA pre-shared key length field accordingly
+
+
+ Specifies that when the security mode is WPA or WPA2 if the PSK mode is enabled.
+ If this is off then EAP mode is used and the list of EAPs needs to be defined.
+
+
+
+
+ The length of the specified pre-shared key (in WPA pre-shared key field)
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in use. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM the string needs to be "+018".
+ The list is in priority order, highest priority first.
+
+
+
+ The username used with EAP-GTC.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with EAP-GTC.
+
+
+
+
+
+ The username used with EAP-TLS.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ Defines which EAP tunneling method is used with EAP-TLS.
+
+
+
+
+
+
+ The username used with EAP-LEAP.
+
+
+ The password used with EAP-LEAP.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ The username used with EAP-SIM.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ Defines which EAP tunneling method is used with EAP-SIM.
+
+
+
+
+
+
+ The username used with EAP-TTLS.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TTLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-TTLS. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with EAP-AKA.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with EAP-AKA.
+
+
+
+
+
+
+ The username used with EAP-PEAP.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether PEAP requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ Is PEAP version 0 allowed. If in doubt enable only this one.
+
+
+
+
+ Is PEAP version 1 allowed.
+
+
+
+
+ Is PEAP version 2 allowed.
+
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-PEAP. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with EAP-MSCHAPv2.
+
+
+ The password used with EAP-MSCHAPv2.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ Defines which EAP tunneling method is used with EAP-MSCHAPv2.
+
+
+
+
+
+ The username used with EAP-FAST.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TTLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-FAST. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ EAP-FAST authenticated provisioning mode allowed
+
+
+
+
+ EAP-FAST unauthenticated provisioning mode allowed
+
+
+
+
+ EAP-FAST warn ADHP no PAC
+
+
+
+
+ EAP-FAST warn ADHP no matching PAC
+
+
+
+
+ EAP-FAST warn not default server
+
+
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with MSCHAPv2.
+
+
+ The password used with MSCHAPv2.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with MSCHAPv2. Needs to be EAP-TTLS.
+
+
+
+
+
+ Circuit-Switched Data connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Username for the connection.
+
+
+ Prompt password on connection set-up time.
+
+
+
+
+ Password.
+
+
+ Password authentication type.
+
+
+
+
+ WAP gateway IP.
+
+
+ Starting page.
+
+
+ WTLS security.
+
+
+
+
+ Connection type.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Default telephone number.
+
+
+ Bearer speed
+
+
+
+
+
+
+
+
+
+
+ Bearer Call Type Isdn
+
+
+
+
+
+ Is callback enabled.
+
+
+
+
+ Callback type.
+
+
+
+
+ Callback number.
+
+
+ Enable compression
+
+
+
+
+ Use login script
+
+
+
+
+ Login script
+
+
+ Modem init string
+
+
+
+
+ High-speed Circuit-Switched Data connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ User name
+
+
+ Prompt password at connection time.
+
+
+
+
+ Password.
+
+
+ Password authentication method.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Default telephone number.
+
+
+ Bearer speed
+
+
+
+
+
+
+
+
+
+
+ Bearer Call Type Isdn
+
+
+
+
+
+ Is callback enabled.
+
+
+
+
+ Callback type.
+
+
+
+
+ Callback number.
+
+
+ Enable compression
+
+
+
+
+ Use login script
+
+
+
+
+ Login script
+
+
+ Modem init string
+
+
+
+
+ LAN connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ LAN interface networks.
+
+
+ LAN interface netmask.
+
+
+ LAN IP Gateway.
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+
+
+ Virtual Private Network connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ The network connection provider IAP name.
+
+
+ Service policy.
+
+
+
+
+ Destination network (SNAP) definitions.
+
+
+ The name that is visible to the user
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Metadata that specifies a few default destination networks that applications can use
+
+
+
+
+
+
+
+ DN protection level. Destination contents mean the connection methods inside the destination and their priorities.
+
+
+
+
+
+ Is DN hidden or not.
+
+
+
+
+ Is DN hidden in CConnDlg or not
+
+
+
+
+ Is DN highlighted or not.
+
+
+
+
+ Icon to be assigned to DN.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of an embedded DN that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ Normal
+ On
+ Continuous
+ Autodetect
+ Analogue
+ Yes
+ Server Number
+ No
+ No
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User Defined
+ 0
+ No
+ No
+ No
+ 11
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Internet
+ 1
+ Internet
+ 2
+ No
+ No
+ Yes
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MMS
+ 2
+ MMS
+ 2
+ No
+ Yes
+ No
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Operator
+ 3
+ Operator
+ 2
+ No
+ No
+ No
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ whenavailable
+ 11
+ Ask once
+
+
+ 1
+ 0
+ 100
+ 1
+ 1
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 253
+ 254
+ 9
+ 0
+ 8
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 4
+ 7
+ 2347
+ 300
+ 1
+ 300
+ -1
+ 1
+ -1
+ -1
+ 1
+ -1
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ IPv4
+ No
+ Normal
+ On
+ Continuous
+ Yes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ IPv4
+ No
+ Normal
+ On
+ Continuous
+ Yes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ No
+ Normal
+ On
+ Continuous
+ Autodetect
+ Analogue
+ Yes
+ Server Number
+ No
+ No
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ Confirm first
+ On
+ Continuous
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ Infrastructure
+ Open
+ No
+ key1
+ Shared
+ 64
+ ASCII
+ 64
+ ASCII
+ 64
+ ASCII
+ 64
+ ASCII
+ No
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ false
+ false
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/comparison_operators.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/comparison_operators.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 1
+ 2
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/eval.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/eval.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+ 0
+
+
+
+ 10
+ false
+ false
+ false
+ false
+
+
+
+
+ Default
+ 0
+
+
+ Stripped 1
+ 1
+
+
+ Stripped 2
+ 2
+
+
+
+ Default
+ 0
+ 0.5
+ false
+
+
+ Full 1
+ 10
+ 1.5
+ true
+
+
+ Full 2
+ 20
+ 2.5
+ false
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/filename_testdata.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/filename_testdata.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ some/folder1
+ sounds/file1.txt
+ Z:\\data\\sound.mp3
+
+ x
+ x
+ x
+ x
+ x
+ x
+ x
+ x
+ x
+ x
+ x
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/testdata.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/testdata.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ image_conf_imakerapi.mk
+
+
+ 0
+ V .50.2009.04.0113 RND
+ myProduct
+ myProduct
+
+
+
+ 5
+ 25
+ 7
+ 5
+ 10
+ 2
+ 5
+ 10
+ 8
+
+
+ String 1
+ String 2
+ x
+ x
+ x
+ x
+ x
+ x
+
+
+ <ударениÑ>
+ <ελληνικά>カタカナελληνικά>
+ ударениÑ>
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/arithmetic.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/arithmetic.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,37 @@
+
+
+
+ True configures Arithmetic.AdditionResult1 = 2 + 6
+ True configures Arithmetic.AdditionResult2 = Arithmetic.Value1 + 6
+ True configures Arithmetic.AdditionResult3 = 2 + Arithmetic.Value2
+ True configures Arithmetic.AdditionResult4 = Arithmetic.Value1 + Arithmetic.Value2
+
+ True configures Arithmetic.SubtractionResult1 = 2 - 6
+ True configures Arithmetic.SubtractionResult2 = Arithmetic.Value1 - 6
+ True configures Arithmetic.SubtractionResult3 = 2 - Arithmetic.Value2
+ True configures Arithmetic.SubtractionResult4 = Arithmetic.Value1 - Arithmetic.Value2
+
+ True configures Arithmetic.MultiplicationResult1 = 2 * 6
+ True configures Arithmetic.MultiplicationResult2 = Arithmetic.Value1 * 6
+ True configures Arithmetic.MultiplicationResult3 = 2 * Arithmetic.Value2
+ True configures Arithmetic.MultiplicationResult4 = Arithmetic.Value1 * Arithmetic.Value2
+
+ True configures Arithmetic.DivisionResult1 = 6 / 2
+ True configures Arithmetic.DivisionResult2 = Arithmetic.Value2 / 4
+ True configures Arithmetic.DivisionResult3 = 10 / Arithmetic.Value1
+ True configures Arithmetic.DivisionResult4 = Arithmetic.Value2 / Arithmetic.Value1
+
+ True configures Arithmetic.MixedResult1 = (6 / 2 + 3 * 9) - 7
+ True configures Arithmetic.MixedResult2 = (6 / 2 + Arithmetic.Value1 * 9) - 7
+ True configures Arithmetic.MixedResult3 = (Arithmetic.Value2 / 2 + Arithmetic.Value1 * 9) - 7
+ True configures Arithmetic.MixedResult4 = (Arithmetic.Value2 / Arithmetic.Value1 + Arithmetic.Value1 * Arithmetic.Value1) - Arithmetic.Value2
+ True configures Arithmetic.MixedResult5 = 4 + 6 / 2 - 3 * 9 + 10 / 5 - 8
+
+ True configures Arithmetic.RealResult1 = 5.0 / 2.0
+ True configures Arithmetic.RealResult2 = Arithmetic.RealValue1 / 2
+ True configures Arithmetic.RealResult3 = 0.25 * Arithmetic.RealValue2
+ True configures Arithmetic.RealResult4 = Arithmetic.RealValue1 / 2.0 * Arithmetic.RealValue2
+
+ True configures Arithmetic.RealCalcIntoIntResult = 0.25 * Arithmetic.RealValue1
+ True configures Arithmetic.IntCalcIntoRealResult = 3 * Arithmetic.Value1
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/commsdat.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/commsdat.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+ (APs.AP != []) or (VPN_APs.VPN_AP != []) configures KCRUidCommsDatCreator.KCommsDatCreatorInputFileName = 'test.xml'
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/comparison_operators.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/comparison_operators.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+
+
+ 0 == 0 configures CompOperTest.LiteralsResult1 = true
+ 0 != 1 configures CompOperTest.LiteralsResult2 = true
+ 1 < 2 configures CompOperTest.LiteralsResult3 = true
+ 2 > 1 configures CompOperTest.LiteralsResult4 = true
+ 1 <= 1 configures CompOperTest.LiteralsResult5 = true
+ 1 <= 2 configures CompOperTest.LiteralsResult6 = true
+ 1 >= 1 configures CompOperTest.LiteralsResult7 = true
+ 2 >= 1 configures CompOperTest.LiteralsResult8 = true
+
+ CompOperTest.Zero == CompOperTest.Zero configures CompOperTest.RefsResult1 = true
+ CompOperTest.Zero != CompOperTest.One configures CompOperTest.RefsResult2 = true
+ CompOperTest.One < CompOperTest.Two configures CompOperTest.RefsResult3 = true
+ CompOperTest.Two > CompOperTest.One configures CompOperTest.RefsResult4 = true
+ CompOperTest.One <= CompOperTest.One configures CompOperTest.RefsResult5 = true
+ CompOperTest.One <= CompOperTest.Two configures CompOperTest.RefsResult6 = true
+ CompOperTest.One >= CompOperTest.One configures CompOperTest.RefsResult7 = true
+ CompOperTest.Two >= CompOperTest.One configures CompOperTest.RefsResult8 = true
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/container_with_rules.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/container_with_rules.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+
+
+
+
+
+ imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget
+ True configures StringConcatenationTest.Result1 = "Test " + "test"
+ True configures StringConcatenationTest.Result2 = StringConcatenationTest.Value1 + " Literal 2"
+
+
+
+
+
+ True configures StringConcatenationTest.Result3 = "Literal 1 " + StringConcatenationTest.Value2
+ True configures StringConcatenationTest.Result4 = StringConcatenationTest.Value1 + StringConcatenationTest.Value2
+ True configures StringConcatenationTest.Result5 = StringConcatenationTest.Value1 + " & " + StringConcatenationTest.Value2
+ True configures StringConcatenationTest.Result6 = StringConcatenationTest.Value1 + u" € カタカナ"
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/eval.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/eval.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,42 @@
+
+
+ True configures EvalTest.StringLenResult = {% len("faklskjh") %}
+ True configures EvalTest.EvalConstantResult = {% SOME_VALUE %}
+ True configures EvalTest.EvalFileImport = {% do_something(SOME_VALUE) %}
+
+ {% ${EvalTest.Bitmask} & 0x1 %} configures EvalTest.Bit0Result = True
+ {% ${EvalTest.Bitmask} & 0x2 %} configures EvalTest.Bit1Result = True
+ True configures EvalTest.Bit2Result = {%
+ bool(${EvalTest.Bitmask} & 0x4)
+ %}
+
+
+ True configures EvalTest.Bit3Result = {% bool(${EvalTest.Bitmask} & 0x8) %}
+
+
+ True configures EvalTest.FullSequence = {% append_stripped_seq_to_full_seq(
+ @{EvalTest.StrippedSequence},
+ @{EvalTest.FullSequence})
+ %}
+
+
+
+ False configures {% @{EvalTest.UnchangedValue}.set_value(54321) %}
+
+ True configures EvalTest.UnicodeResult1 = {% u'100€' %}
+ True configures EvalTest.UnicodeResult2 = {% @{ударениÑ.ελληνικά}.get_value() %}
+
+ True configures EvalTest.EvalBuiltinResult = {% ruleml.configuration.get_name() %}
+
+ SOME_VALUE = 12345
+
+
+def append_stripped_seq_to_full_seq(stripped_seq, full_seq):
+ stripped_values = stripped_seq.get_value()
+ full_values = full_seq.get_value()
+ for sv in stripped_values:
+ full_values.append([sv[0], sv[1], '0.1', 'false'])
+ return full_values
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/filename_rules.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/filename_rules.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+
+
+ True configures FilenamejoinTest.Result1 = FilenamejoinTest.String1 filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result2 = "some/content/dir/somefile.csv" filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result3 = "some/content/dir/" filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result4 = "some\\content\\dir\\somefile.csv" filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result5 = "some\\content\\dir\\" filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result6 = "Z:\\\\some\\\\content\\\\dir\\\\somefile.csv" filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result7 = "Z:\\\\some\\\\content\\\\dir\\\\" filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result8 = "somedir" filenamejoin FilenamejoinTest.File1.localPath
+ True configures FilenamejoinTest.Result9 = "somedir" filenamejoin "somefile.txt"
+ True configures FilenamejoinTest.Result10 = "somedir" filenamejoin "somefile.txt" + ';' + r'Z:\\some\\dir\\' filenamejoin FilenamejoinTest.File1.localPath
+ True and FilenamejoinTest.String1==r'Z:\\data\\sound.mp3' and True configures FilenamejoinTest.Result11 = "some" + "dir" filenamejoin "somefile.txt"
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/rules.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/rules.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+
+
+ imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget
+ mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True
+ mms.imagesize == 'small' configures pd.ref1 = False and pd.ref2 = True
+ mms.imagesize == 'extrasmall' configures pd.ref1 = False and pd.ref2 = False
+ mms.imagesize == 'extralarge' configures pd.ref1 = True and pd.ref2 = False
+ imakerapi.outputLocationY == None configures imakerapi.outputLocationY = 'hello'
+ operations.minus == 5 configures operations.minus = operations.minus1 - operations.minus2
+ operations.minus1 == 25 configures operations.minus1 = operations.minus3 * operations.minus2
+ operations.minus4 == 10 configures operations.minus4 = operations.minus4 / operations.minus5
+ operations.minus6 == 5 configures operations.minus6 = operations.minus7 + operations.minus8
+
+ True configures StringConcatenationTest.Result1 = "Test " + "test"
+ True configures StringConcatenationTest.Result2 = StringConcatenationTest.Value1 + " Literal 2"
+ True configures StringConcatenationTest.Result3 = "Literal 1 " + StringConcatenationTest.Value2
+ True configures StringConcatenationTest.Result4 = StringConcatenationTest.Value1 + StringConcatenationTest.Value2
+ True configures StringConcatenationTest.Result5 = StringConcatenationTest.Value1 + " & " + StringConcatenationTest.Value2
+ True configures StringConcatenationTest.Result6 = StringConcatenationTest.Value1 + u" € カタカナ"
+
+ True configures ударениÑ.ελληνικά = ударениÑ.ελληνικά + u" € カタカナ"
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/scripts/test_eval.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/scripts/test_eval.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+def do_something(param):
+ return param + 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_eval.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_eval.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,108 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import re
+
+import __init__
+
+from ruleplugin import ruleml, relations
+from cone.public import api, exceptions
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class MockObject(object):
+ pass
+
+class MockFeature(object):
+ def __init__(self, ref, feature_values):
+ self.ref = ref
+ self.feature_values = feature_values
+
+ def get_value(self):
+ return self.feature_values[self.ref]
+
+ def set_value(self, value):
+ self.feature_values[self.ref] = value
+
+class MockConfigurationContext(object):
+ def __init__(self, feature_values):
+ self.data = MockObject()
+ default_view = MockObject()
+ default_view.get_feature = lambda ref: MockFeature(ref, feature_values)
+ self.data.get_default_view = lambda: default_view
+ self.ref_eval_callback = None
+
+class MockExpression(object):
+ def __init__(self, expression):
+ self.expression = repr(expression)
+
+class TestEvalExpression(unittest.TestCase):
+ def test_extract_refs(self):
+ ee = relations.EvalExpression(
+ None, MockExpression("'%05d 0x%08X %d' % (${Feature1.Setting1}.get_value(), ${Feature1.Setting2}.get_value(), ${Feature2.Setting1}.get_value())"))
+ self.assertEquals(sorted(ee.extract_refs()), sorted(["Feature1.Setting1", "Feature1.Setting2", "Feature2.Setting1"]))
+
+ ee = relations.EvalExpression(None, MockExpression("'%05d 0x%08X %d' % (1, 2, 3)"))
+ self.assertEquals(ee.extract_refs(), [])
+
+ ee = relations.EvalExpression(None, MockExpression(u"${ударениÑ.ελληνικά}"))
+ self.assertEquals(ee.extract_refs(), [u'ударениÑ.ελληνικά'])
+
+ def test_execute(self):
+ feature_values = {
+ "Feature1.Setting1": 16,
+ "Feature1.Setting2": 32,
+ "Feature2.Setting1": 64,
+ u'ударениÑ.ελληνικά': 100,
+ }
+ context = MockConfigurationContext(feature_values)
+
+ ee = relations.EvalExpression(None,
+ MockExpression("'%05d 0x%08X %d' % (@{Feature1.Setting1}.get_value(), @{Feature1.Setting2}.get_value(), @{Feature2.Setting1}.get_value())"))
+ self.assertEquals(ee.eval(context), "00016 0x00000020 64")
+
+ ee = relations.EvalExpression(None, MockExpression("'%05d 0x%08X %d' % (1, 2, 3)"))
+ self.assertEquals(ee.eval(context), "00001 0x00000002 3")
+
+ ee = relations.EvalExpression(None, MockExpression(u"'%d' % @{ударениÑ.ελληνικά}.get_value()"))
+ self.assertEquals(ee.eval(context), "100")
+
+class TestReplaceEvalBlocks(unittest.TestCase):
+ def test_replace_eval_blocks(self):
+ replace = ruleml.RuleImplReader2._replace_eval_blocks
+
+ orig = """some.setting configures x = y"""
+ self.assertEquals(replace(orig), orig)
+
+ orig = """some.setting configures x = {% do_something(@{Fea.Set}) %}"""
+ self.assertEquals(replace(orig), """some.setting configures x = __eval__ 'do_something(@{Fea.Set})'""")
+
+ orig = """{% 'test' %}"""
+ self.assertEquals(replace(orig), '''__eval__ "'test'"''')
+ orig = """{%'test'%}"""
+ self.assertEquals(replace(orig), '''__eval__ "'test'"''')
+
+ orig = """{% len(@{Fea.Set}.get_value()) %} == 3 configures x = {% do_something('test') %}"""
+ self.assertEquals(replace(orig), '''__eval__ 'len(@{Fea.Set}.get_value())' == 3 configures x = __eval__ "do_something('test')"''')
+
+ orig = u"True configures X.Y = {% len(@{ударениÑ.ελληνικά}.get_value()) %}"
+ self.assertEquals(replace(orig), u"True configures X.Y = __eval__ %r" % u"len(@{ударениÑ.ελληνικά}.get_value())")
+
+if __name__ == "__main__":
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_parseruleml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_parseruleml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,97 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from ruleplugin import ruleml, relations
+from cone.public import api, exceptions, utils, plugin
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+ruleml_string = \
+'''
+
+ imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget
+ imaker.imagename configures imakerapi.outputLocation = imaker.imagename
+
+'''
+
+class TestParseRuleimpl(unittest.TestCase):
+ def setUp(self): relations.register()
+ def tearDown(self): relations.unregister()
+
+ def test_parse_rules(self):
+ etree = ElementTree.fromstring(ruleml_string)
+ reader = ruleml.RuleImplReader2(None, None)
+ rules = reader.parse_rules(etree)
+ self.assertTrue(isinstance(rules[0],relations.ConfigureRelation))
+ self.assertTrue(isinstance(rules[1],relations.ConfigureRelation))
+ self.assertTrue(rules[0].has_ref('imaker.imagetarget'))
+ self.assertFalse(rules[0].has_ref('imakerapi.imagename'))
+ self.assertTrue(rules[0].has_ref('imakerapi.outputLocation'))
+
+
+class TestRulemlFromFile(unittest.TestCase):
+ def setUp(self): pass
+ def tearDown(self): relations.unregister()
+
+ def test_create_from_file(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+ config = project.get_configuration('root.confml')
+ ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/rules.ruleml', config)[0]
+ relation_container = ruleimpl.get_relation_container()
+ self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+ self.assertEquals(relation_container.get_relation_count(), 17)
+
+ def test_create_from_file_with_common_container(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+ config = project.get_configuration('root.confml')
+ ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/container_with_rules.ruleml', config)[0]
+ relation_container = ruleimpl.get_relation_container()
+ self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+ self.assertEquals(relation_container.get_relation_count(), 7)
+
+ def test_create_from_file_filename(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+ config = project.get_configuration('root.confml')
+ ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/filename_rules.ruleml', config)[0]
+ relation_container = ruleimpl.get_relation_container()
+ self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+ self.assertEquals(relation_container.get_relation_count(), 11)
+
+ def test_parse_eval(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+ config = project.get_configuration('root.confml')
+ ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/eval.ruleml', config)[0]
+ relation_container = ruleimpl.get_relation_container()
+ self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+ self.assertEquals(relation_container.get_relation_count(), 12)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_empty_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_empty_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,73 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import logging
+
+import __init__
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from ruleplugin import ruleml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'rule')
+
+class TestRuleEmptyPlugin(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+
+ def test_rule_with_empty_value1(self):
+ return
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+ config = project.get_configuration('root.confml')
+ implcontainer = plugin.get_impl_set(config)
+ implcontainer.generate()
+ lastconfig = config.get_last_configuration()
+ self.assertEquals(lastconfig.get_path(),ruleml.RuleImpl.AUTOCONFIGURATION_CONFML)
+ self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_ref(),'outputLocation')
+ self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_value(),'2')
+ self.assertEquals(lastconfig.get_data('imakerapi.outputLocationY').get_value(),'hello')
+ self.assertEquals(lastconfig.get_data('operations.minus').get_value(),'18')
+ self.assertEquals(lastconfig.get_data('operations.minus1').get_value(),'35')
+ self.assertEquals(lastconfig.get_data('operations.minus4').get_value(),'5')
+ project.close()
+
+
+ def test_rule_with_empty_value2(self):
+ return
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'rule/config_project/platforms/customsw'), "a" ))
+ config = project.get_configuration('root.confml')
+ implcontainer = plugin.get_impl_set(config)
+ implcontainer.generate()
+ lastconfig = config.get_last_configuration()
+ self.assertEquals(lastconfig.get_data('operations.minus').get_value(),'18')
+ self.assertEquals(lastconfig.get_data('operations.minus1').get_value(),'35')
+ self.assertEquals(lastconfig.get_data('operations.minus4').get_value(),'5')
+ self.assertEquals(lastconfig.get_data('operations.minus6').get_value(),'19')
+ self.assertEquals(lastconfig.get_data('operations.string1').get_value(),'HelloWorld')
+ project.close()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import logging
+import __init__
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from ruleplugin import ruleml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'ruleproject')
+
+class TestRulePlugin(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+class TestRulePluginOnFileStorage(unittest.TestCase):
+ def test_get_impl_container(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+ config = project.get_configuration('root.confml')
+ implcontainer = plugin.get_impl_set(config, 'ruleml$')
+ impl = implcontainer.get_implementations_by_file('implml/rules.ruleml')[0]
+
+ self.assertEquals(None, impl.get_refs())
+ self.assertEquals([], impl.list_output_files())
+
+ def test_impl_container_execute_pre_rules(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+ config = project.get_configuration('root.confml')
+
+ implcontainer = plugin.get_impl_set(config, 'ruleml$')
+ ruleimpl = implcontainer.get_implementations_by_file('implml/container_with_rules.ruleml')[0]
+ context = plugin.GenerationContext()
+ context.phase = "pre"
+ ruleimpl.generate(context)
+
+ lastconfig = config.get_last_configuration()
+ self.assertEquals(lastconfig.get_path(), plugin.AUTOCONFIG_CONFML)
+ self.assertEquals(lastconfig.list_all_datas(),['imakerapi',
+ 'imakerapi.outputLocation',
+ 'StringConcatenationTest',
+ 'StringConcatenationTest.Result1',
+ 'StringConcatenationTest.Result2'])
+
+ self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_ref(),'outputLocation')
+ self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_value(),'2')
+ project.close()
+
+ def test_impl_container_execute_rules(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+ config = project.get_configuration('root.confml')
+
+ implcontainer = plugin.get_impl_set(config, 'ruleml$')
+ implcontainer.generate()
+
+ lastconfig = config.get_last_configuration()
+ self.assertEquals(lastconfig.get_path(), plugin.AUTOCONFIG_CONFML)
+ self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_ref(),'outputLocation')
+ self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_value(),'2')
+ project.close()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin_errors.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin_errors.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,110 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import logging
+import __init__
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from ruleplugin import ruleml
+from testautomation.base_testcase import BaseTestCase
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'errorruleproject')
+
+class TestErrorReporting(BaseTestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def _prepare_workdir(self, workdir):
+ workdir = os.path.join(ROOT_PATH, workdir)
+ self.recreate_dir(workdir)
+ return workdir
+
+ def _prepare_log(self, log_file, level=logging.DEBUG, formatter="%(levelname)s - %(name)s - %(message)s", logger='cone'):
+ FULL_PATH = os.path.join(ROOT_PATH, "temp", log_file)
+ self.remove_if_exists(FULL_PATH)
+ self.create_dir_for_file_path(FULL_PATH)
+
+ handler = logging.FileHandler(FULL_PATH)
+ handler.setLevel(level)
+ frm = logging.Formatter(formatter)
+ handler.setFormatter(frm)
+ logger = logging.getLogger(logger)
+ logger.addHandler(handler)
+
+ return [FULL_PATH, handler, logger]
+
+ def _execute_rules(self, project_location):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH, project_location)))
+ config = project.get_configuration('root.confml')
+
+ implcontainer = plugin.get_impl_set(config, r'\.ruleml$')
+ implcontainer.get_relation_container().execute()
+ lastconfig = config.get_last_configuration()
+ project.close()
+
+ def test_terminal_expression_repr(self):
+ log_file, handler, logger = self._prepare_log('test1.log')
+ self._execute_rules('errorruleproject/test1')
+ logger.removeHandler(handler)
+
+ self.assert_file_does_not_contain(log_file, " this is invalid python code'")
+ self.assert_file_contains(log_file, "WARNING - cone.ruleml - Invalid syntax in eval: -> this is invalid python code")
+ self.assert_file_contains(log_file, "ERROR - cone.ruleml_relation_container(implml/invalid_python_eval.ruleml) - '-> this is invalid python code'")
+
+ def test_invalid_python_code_eval_globals(self):
+ log_file, handler, logger = self._prepare_log('test3.log')
+ self._execute_rules('errorruleproject/test3')
+ logger.removeHandler(handler)
+ self.assert_file_contains(log_file, "WARNING - cone.ruleml(implml/invalid_python_eval.ruleml) - Cannot import eval file: implml/scripts/test_eval.py. Exception: invalid syntax (, line 17)")
+
+ def test_invalid_file_reference_in_eval_globals_file_attribute(self):
+ log_file, handler, logger = self._prepare_log('test4.log')
+ self._execute_rules('errorruleproject/test4')
+ logger.removeHandler(handler)
+ self.assert_file_contains(log_file, "WARNING - cone.ruleml(implml/invalid_python_eval.ruleml) - Cannot import eval file: implml/scripts/not_valid_filename.py. Exception: implml/scripts/not_valid_filename.py, [Errno 2] No such file or directory:")
+ self.assert_file_contains(log_file, '/implml/scripts/not_valid_filename.py')
+
+ def test_runtime_error_when_running_an_eval_block_inside_rule(self):
+ log_file, handler, logger = self._prepare_log('test5.log')
+ self._execute_rules('errorruleproject/test5')
+ logger.removeHandler(handler)
+
+ self.assert_file_contains(log_file, "Execution failed for eval: 7/0 : integer division or modulo by zero")
+
+ def test_references_non_existent_settings(self):
+ log_file, handler, logger = self._prepare_log('test6.log')
+ self._execute_rules('errorruleproject/test6')
+ logger.removeHandler(handler)
+ #self.assert_file_contains(log_file, "Execution failed for eval: 7/0 : integer division or modulo by zero")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rules.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rules.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,186 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import __init__
+
+from ruleplugin import ruleml
+from cone.public import api, plugin
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestRuleExecutes(unittest.TestCase):
+
+ def setUp(self):
+ self.project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+ self.config = self.project.get_configuration('root.confml')
+
+ def tearDown(self):
+ self.project.close()
+
+ def _execute_rules(self, impl_filter):
+ implcontainer = plugin.get_impl_set(self.config, impl_filter)
+ context = plugin.GenerationContext()
+ implcontainer.generate(context)
+ return context.results
+
+ def test_arithmetic_operations(self):
+ self._execute_rules(r'^implml/arithmetic\.ruleml$')
+
+ # Values used in the ConfML (the calculations are duplicated here to make
+ # the tests more readable)
+ value1 = 5
+ value2 = 20
+ config = self.config
+ self.assert_setting_equals(config, 'Arithmetic.AdditionResult1', 2 + 6)
+ self.assert_setting_equals(config, 'Arithmetic.AdditionResult2', value1 + 6)
+ self.assert_setting_equals(config, 'Arithmetic.AdditionResult3', 2 + value2)
+ self.assert_setting_equals(config, 'Arithmetic.AdditionResult4', value1 + value2)
+
+ self.assert_setting_equals(config, 'Arithmetic.SubtractionResult1', 2 - 6)
+ self.assert_setting_equals(config, 'Arithmetic.SubtractionResult2', value1 - 6)
+ self.assert_setting_equals(config, 'Arithmetic.SubtractionResult3', 2 - value2)
+ self.assert_setting_equals(config, 'Arithmetic.SubtractionResult4', value1 - value2)
+
+ self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult1', 2 * 6)
+ self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult2', value1 * 6)
+ self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult3', 2 * value2)
+ self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult4', value1 * value2)
+
+ self.assert_setting_equals(config, 'Arithmetic.DivisionResult1', 6 / 2)
+ self.assert_setting_equals(config, 'Arithmetic.DivisionResult2', value2 / 4)
+ self.assert_setting_equals(config, 'Arithmetic.DivisionResult3', 10 / value1)
+ self.assert_setting_equals(config, 'Arithmetic.DivisionResult4', value2 / value1)
+
+ self.assert_setting_equals(config, 'Arithmetic.MixedResult1', (6 / 2 + 3 * 9) - 7)
+ self.assert_setting_equals(config, 'Arithmetic.MixedResult2', (6 / 2 + value1 * 9) - 7)
+ self.assert_setting_equals(config, 'Arithmetic.MixedResult3', (value2 / 2 + value1 * 9) - 7)
+ self.assert_setting_equals(config, 'Arithmetic.MixedResult4', (value2 / value1 + value1 * value1) - value2)
+ self.assert_setting_equals(config, 'Arithmetic.MixedResult5', 4 + 6 / 2 - 3 * 9 + 10 / 5 - 8)
+
+ rvalue1 = float(value1)
+ rvalue2 = float(value2)
+ self.assert_setting_equals(config, 'Arithmetic.RealResult1', 5.0 / 2.0)
+ self.assert_setting_equals(config, 'Arithmetic.RealResult2', rvalue1 / 2.0)
+ self.assert_setting_equals(config, 'Arithmetic.RealResult3', 0.25 * rvalue2)
+ self.assert_setting_equals(config, 'Arithmetic.RealResult4', rvalue1 / 2.0 * rvalue2)
+#
+ self.assert_setting_equals(config, 'Arithmetic.RealCalcIntoIntResult', int(0.25 * rvalue1))
+ self.assert_setting_equals(config, 'Arithmetic.IntCalcIntoRealResult', float(3 * value1))
+
+ def test_string_concatenation(self):
+ self._execute_rules(r'^implml/rules\.ruleml$')
+
+ config = self.config
+ self.assert_setting_equals(config, 'StringConcatenationTest.Result1', 'Test test')
+ self.assert_setting_equals(config, 'StringConcatenationTest.Result2', 'String 1 Literal 2')
+ self.assert_setting_equals(config, 'StringConcatenationTest.Result3', 'Literal 1 String 2')
+ self.assert_setting_equals(config, 'StringConcatenationTest.Result4', 'String 1String 2')
+ self.assert_setting_equals(config, 'StringConcatenationTest.Result5', 'String 1 & String 2')
+ self.assert_setting_equals(config, 'StringConcatenationTest.Result6', u'String 1 € カタカナ')
+
+ self.assert_setting_equals(config, u'ударениÑ.ελληνικά', u'カタカナ € カタカナ')
+
+
+ def test_filenamejoin(self):
+ self._execute_rules(r'^implml/filename_rules\.ruleml$')
+
+ config = self.config
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result1', r'Z:\\data\\file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result2', r'some/content/dir/file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result3', r'some/content/dir/file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result4', r'some\content\dir\file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result5', r'some\content\dir\file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result6', r'Z:\\some\\content\\dir\\file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result7', r'Z:\\some\\content\\dir\\file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result8', r'somedir/file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result9', r'somedir/somefile.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result10', r'somedir/somefile.txt;Z:\\some\\dir\\file1.txt')
+ self.assert_setting_equals(config, 'FilenamejoinTest.Result11', r'somedir/somefile.txt')
+
+ def test_comparison_operators(self):
+ self._execute_rules(r'^implml/comparison_operators\.ruleml$')
+
+ for i in xrange(1, 8):
+ ref = 'CompOperTest.LiteralsResult%d' % i
+ self.assert_setting_equals(self.config, ref, True, "Setting %s is not True" % ref)
+
+ for i in xrange(1, 8):
+ ref = 'CompOperTest.RefsResult%d' % i
+ self.assert_setting_equals(self.config, ref, True, "Setting %s is not True" % ref)
+
+ def test_eval(self):
+ config = self.config
+
+ self.assert_setting_equals(config, 'EvalTest.FullSequence',
+ [['Full 1', '10', '1.5', 'true'],
+ ['Full 2', '20', '2.5', 'false']])
+
+ self._execute_rules(r'^implml/eval\.ruleml$')
+
+ self.assert_setting_equals(config, 'EvalTest.StringLenResult', 8)
+ self.assert_setting_equals(config, 'EvalTest.EvalConstantResult', 12345)
+ self.assert_setting_equals(config, 'EvalTest.EvalFileImport', 12346)
+ self.assert_setting_equals(config, 'EvalTest.UnchangedValue', 0)
+ self.assert_setting_equals(config, 'EvalTest.UnicodeResult1', u'100€')
+ self.assert_setting_equals(config, 'EvalTest.UnicodeResult2', u'カタカナ')
+ self.assert_setting_equals(config, 'EvalTest.Bit0Result', False)
+ self.assert_setting_equals(config, 'EvalTest.Bit1Result', True)
+ self.assert_setting_equals(config, 'EvalTest.Bit2Result', False)
+ self.assert_setting_equals(config, 'EvalTest.Bit3Result', True)
+ self.assert_setting_equals(config, 'EvalTest.FullSequence',
+ [['Full 1', '10', '1.5', 'true'],
+ ['Full 2', '20', '2.5', 'false'],
+ ['Stripped 1', '1', '0.1', 'false'],
+ ['Stripped 2', '2', '0.1', 'false']])
+ self.assert_setting_equals(config, 'EvalTest.EvalBuiltinResult', 'ruleml_test_config')
+
+ def assert_setting_equals(self, config, setting, expected_value, msg=None):
+ if msg == None:
+ self.assertEquals(config.get_default_view().get_feature(setting).get_value(), expected_value)
+ else:
+ self.assertEquals(config.get_default_view().get_feature(setting).get_value(), expected_value, msg)
+
+ def test_rule_execution_results(self):
+ results = self._execute_rules(r'^implml/rules\.ruleml$')
+
+ def r(index, input_refs, affected_refs):
+ return plugin.RelationExecutionResult(index = index,
+ source = 'implml/rules.ruleml',
+ input_refs = input_refs,
+ affected_refs = affected_refs)
+ expected = [
+ r(1, ['imaker.imagetarget'], ['imakerapi.outputLocation']),
+ r(6, ['imakerapi.outputLocationY'], ['imakerapi.outputLocationY']),
+ r(7, ['operations.minus'], ['operations.minus']),
+ r(8, ['operations.minus1'], ['operations.minus1']),
+ r(9, ['operations.minus4'], ['operations.minus4']),
+ r(10, ['operations.minus6'], ['operations.minus6']),
+ r(11, [], ['StringConcatenationTest.Result1']),
+ r(12, [], ['StringConcatenationTest.Result2']),
+ r(13, [], ['StringConcatenationTest.Result3']),
+ r(14, [], ['StringConcatenationTest.Result4']),
+ r(15, [], ['StringConcatenationTest.Result5']),
+ r(16, [], ['StringConcatenationTest.Result6']),
+ r(17, [], [u'ударениÑ.ελληνικά']),
+ ]
+
+ self.assertEquals(results, expected)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeRulePlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from ruleplugin import __version__
+
+setup(
+ name = "coneruleplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "ruleplugin.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine rule plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware", # project home page, if any
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['ruleml_1 = ruleplugin.ruleml:RuleImplReader1',
+ 'ruleml_2 = ruleplugin.ruleml:RuleImplReader2']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/Jinja2-2.1.1-py2.5-win32.egg
Binary file configurationengine/source/plugins/common/ConeTemplatePlugin/Jinja2-2.1.1-py2.5-win32.egg has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from templatemlplugin import __version__
+
+setup(
+ name = "conetemplateplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "plugintemplate.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine Configuration Tool Template plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['templateml = templatemlplugin.templatemlplugin:TemplatemlImplReader']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
+
+__all__ = ['templatemlplugin']
+
+import pkg_resources
+import sys,os
+
+
+try:
+ pkg_resources.require("Cone")
+except pkg_resources.DistributionNotFound:
+ ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+ sys.path.append(ROOT_PATH)
+ sys.path.append(os.path.join(ROOT_PATH,'..'))
+ sys.path.append(os.path.join(ROOT_PATH,'../..'))
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/templatemlplugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/templatemlplugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,562 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+Template plugin for ConE that handles templateml files. Utilizes Jinja template engine.
+'''
+
+import re
+import os
+import sys
+import logging
+import codecs
+import xml.parsers.expat
+from jinja2 import Environment, PackageLoader, FileSystemLoader, Template, DictLoader
+import traceback
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+try:
+ from cElementTree import ElementInclude
+except ImportError:
+ try:
+ from elementtree import ElementInclude
+ except ImportError:
+ try:
+ from xml.etree import cElementInclude as ElementInclude
+ except ImportError:
+ from xml.etree import ElementInclude
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+from cone.confml import persistentconfml
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TemplatemlImpl(plugin.ImplBase):
+
+ context = None
+
+ """
+ Implementation class of template plugin.
+ """
+
+ IMPL_TYPE_ID = "templateml"
+
+
+ def __init__(self,ref,configuration, reader=None):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.logger = logging.getLogger('cone.templateml(%s)' % self.ref)
+ self.errors = False
+ self.reader = reader
+ if self.reader and self.reader.tags:
+ self.set_tags(self.reader.tags)
+
+ def get_context(self):
+ if TemplatemlImpl.context == None:
+ TemplatemlImpl.context = self.create_dict()
+
+ return TemplatemlImpl.context
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ """
+
+ self.create_output()
+ return
+
+ def create_output(self, layers=None):
+ generator = Generator(self.reader.outputs, self.reader.filters, self.get_context(), self.configuration)
+ generator.generate(self.output, self.ref)
+ return
+
+ def get_refs(self):
+ refs = []
+ for output in self.reader.outputs:
+ template = output.template.template
+ refs.extend(self._extract_refs_from_template(template))
+ return refs
+
+ @classmethod
+ def _extract_refs_from_template(cls, template_text):
+ refs = []
+ pattern = re.compile(r'feat_tree\.((?:\.?\w+)*)', re.UNICODE)
+ for m in re.finditer(pattern, template_text):
+ ref = m.group(1)
+
+ # ref may now be e.g. 'MyFeature.MySetting._value', so
+ # remove the last part if it starts with an underscore
+ index = ref.rfind('.')
+ if index != -1 and index < len(ref) and ref[index + 1] == '_':
+ ref = ref[:index]
+
+ refs.append(ref)
+ return refs
+
+ def has_ref(self, refs):
+ """
+ @returns True if the implementation uses the given ref as input value.
+ Otherwise return False.
+ """
+
+ # Does not support template inheritance
+
+ if not isinstance(refs, list):
+ refs = [refs]
+
+ for output in self.reader.outputs:
+ if re.search("feat_list.*", output.template.template) != None:
+ return True
+
+ refs_in_templates = self.get_refs()
+
+ for ref in refs:
+ if ref in refs_in_templates:
+ return True
+ return False
+
+
+ def list_output_files(self):
+ """ Return a list of output files as an array. """
+ result = []
+ for output in self.reader.outputs:
+ result.append(os.path.normpath(os.path.join(self.output, output.path, output.filename)))
+ return result
+
+ def create_dict(self):
+ """
+ Creates dict from configuration that can be passed to template engine.
+ """
+
+ context_dict = {}
+
+ if self.configuration:
+ dview = self.configuration.get_default_view()
+ feat_list = []
+ feat_tree = {}
+
+ def add_feature(feature, feature_dict):
+ fea_dict = FeatureDictProxy(feature)
+ feat_list.append(fea_dict)
+ feature_dict[feature.ref] = fea_dict
+
+ # Recursively add sub-features
+ for sfeat in feature.list_features():
+ add_feature(feature.get_feature(sfeat), fea_dict)
+
+ for fea in dview.list_features():
+ add_feature(dview.get_feature(fea), feat_tree)
+
+ context_dict['feat_list'] = feat_list
+ context_dict['feat_tree'] = feat_tree
+ context_dict['configuration'] = self.configuration
+
+ return context_dict
+
+def _expand_refs(text, config):
+ if config is not None:
+ return utils.expand_refs_by_default_view(text, config.get_default_view())
+ else:
+ return text
+
+def _read_relative_file(configuration, relative_path, file_path):
+ """
+ Read data from a file relative to the given other file path.
+ """
+ # Get the actual path (relative to the current file)
+ base_path = os.path.dirname(file_path)
+ tempfile_path = os.path.normpath(os.path.join(base_path, relative_path)).replace('\\', '/')
+
+ # Read the file
+ resource = configuration.get_resource(tempfile_path)
+ try: return resource.read()
+ finally: resource.close()
+
+class TemplatemlImplReader(plugin.ReaderBase):
+ """
+ Parses a single templateml file
+ """
+ NAMESPACE = 'http://www.s60.com/xml/templateml/1'
+ FILE_EXTENSIONS = ['templateml']
+
+ def __init__(self, resource_ref=None, configuration=None):
+ self.desc = None
+ self.namespaces = [self.NAMESPACE]
+ self.outputs = None
+ self.filters = None
+ self.tags = None
+ self.resource_ref = resource_ref
+ self.configuration = configuration
+
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = TemplatemlImplReader(resource_ref, configuration)
+ reader.from_elementtree(etree)
+ return TemplatemlImpl(resource_ref, configuration, reader)
+
+ def fromstring(self, xml_string):
+ etree = ElementTree.fromstring(xml_string)
+ self.from_elementtree(etree)
+
+ def from_elementtree(self, etree):
+ ElementInclude.include(etree)
+ self.desc = self.parse_desc(etree)
+ self.outputs = self.parse_outputs(etree)
+ self.filters = self.parse_filters(etree)
+ self.tags = self.parse_tags(etree)
+
+ def parse_desc(self,etree):
+ desc = ""
+ desc_elem = etree.find("{%s}desc" % self.namespaces[0])
+ if desc_elem != None:
+ desc = desc_elem.text
+ return desc
+
+ def parse_filters(self, etree):
+ filters = []
+ filter_elems = etree.findall("{%s}filter" % self.namespaces[0])
+ for filter_elem in filter_elems:
+ if filter_elem != None:
+ filter = Filter()
+
+ if filter_elem.get('name') != None:
+ name = filter_elem.get('name')
+ if self.configuration != None:
+ name = utils.expand_refs_by_default_view(name, self.configuration.get_default_view())
+ filter.set_name(name)
+ if filter_elem.get('file') != None:
+ file = filter_elem.get('file')
+ if self.configuration != None:
+ file = utils.expand_refs_by_default_view(file, self.configuration.get_default_view())
+ filter.set_path(file)
+ if filter_elem.text != None:
+ filter.set_code(filter_elem.text)
+ if filter_elem.get('file') != None:
+ logging.getLogger('cone.templateml').warning("In filter element file attribute and text defined. Using filter found from file attribute.")
+ filters.append(filter)
+ return filters
+
+ def parse_tags(self, etree):
+ tags = {}
+ for tag in etree.getiterator("{%s}tag" % self.namespaces[0]):
+ tagname = tag.get('name','')
+ tagvalue = tag.get('value')
+ values = tags.get(tagname,[])
+ values.append(tagvalue)
+ tags[tagname] = values
+ return tags
+
+ def parse_template(self, output_elem):
+ tempfile = TempFile()
+ template_elems = output_elem.findall("{%s}template" % self.namespaces[0])
+
+ for template_elem in template_elems:
+ if template_elem.text != None:
+ tempfile.set_template(template_elem.text)
+ else:
+ for selem in template_elem:
+ tempfile.set_template(selem.text)
+
+ if template_elem.get('file') != None:
+ file = template_elem.get('file')
+ if template_elem.text != None:
+ logging.getLogger('cone.templateml').warning("In template element file attribute and text defined. Using template found from file attribute.")
+ template_text = _read_relative_file(self.configuration, file, self.resource_ref)
+ tempfile.set_template(template_text)
+ return tempfile
+
+ def parse_outputs(self, etree):
+ outputs = []
+ output_elems = etree.findall("{%s}output" % self.namespaces[0])
+ for output_elem in output_elems:
+ if output_elem != None:
+ outputfile = OutputFile()
+ if output_elem.get('encoding') != None:
+ encoding = output_elem.get('encoding')
+ # Check the encoding
+ try:
+ codecs.lookup(encoding)
+ except LookupError:
+ raise exceptions.ParseError("Invalid output encoding: %s" % encoding)
+
+ if self.configuration != None:
+ encoding = utils.expand_refs_by_default_view(encoding, self.configuration.get_default_view())
+ outputfile.set_encoding(encoding)
+ if output_elem.get('file') != None:
+ file = output_elem.get('file')
+
+ if self.configuration != None:
+ file = utils.expand_refs_by_default_view(file, self.configuration.get_default_view())
+ outputfile.set_filename(file)
+ if output_elem.get('dir') != None:
+ dir = output_elem.get('dir')
+ if self.configuration != None:
+ dir = utils.expand_refs_by_default_view(dir, self.configuration.get_default_view())
+ outputfile.set_path(dir)
+ if output_elem.get('ref'):
+ # Fetch the output value from a configuration reference
+ fea = self.configuration.get_default_view().get_feature(output_elem.get('ref'))
+ outputfile.set_filename(fea.value)
+ if output_elem.get('bom'):
+ outputfile.bom = output_elem.get('bom').lower() in ('1', 'true', 't', 'yes', 'y')
+ outputfile.set_template(self.parse_template(output_elem))
+ outputfile.set_filters(self.parse_filters(output_elem))
+ outputs.append(outputfile)
+ return outputs
+
+class Generator(object):
+ """
+ Class that generates
+ """
+
+ def __init__(self, outputs, filters, context, configuration=None):
+ self.outputs = outputs
+ self.filters = filters
+ self.context = context
+ self.configuration = configuration
+
+ def generate(self, output_path, ref):
+ """
+ Generates output based on templates
+ """
+ if self.outputs != None:
+
+ for output in self.outputs:
+ try:
+ logging.getLogger('cone.templateml').debug(output)
+ out_path = os.path.abspath(os.path.join(output_path, output.path))
+ if out_path != '':
+ if not os.path.exists(out_path):
+ os.makedirs(out_path)
+
+ out_file = open(os.path.join(out_path, output.filename), 'wb')
+
+ if output.template.path:
+ output.template.template = _read_relative_file(self.configuration, output.template.path, ref)
+
+ dict_loader = DictLoader({'template': output.template.template})
+ env = Environment(loader=dict_loader)
+
+ # Common filters
+ for filter in self.filters:
+
+ if filter.path:
+ filter.code = _read_relative_file(self.configuration, filter.path, ref)
+
+ if not filter.code:
+ logging.getLogger('cone.templateml').warning("Skipping empty filter definition.")
+ else:
+ env.filters[str(filter.name)] = eval(filter.code)
+
+ # Output file specific filters
+ for filter in output.filters:
+ if filter.path:
+ filter.code = _read_relative_file(self.configuration, filter.path, ref)
+
+ if not filter.code:
+ logging.getLogger('cone.templateml').warning("Skipping empty filter definition.")
+ else:
+ env.filters[str(filter.name)] = eval(filter.code)
+
+ template = env.get_template('template')
+
+ file_string = template.render(self.context)
+ out_file.write(self._encode_data(file_string, output.encoding, output.bom))
+ out_file.close()
+
+ except Exception, e:
+ logging.getLogger('cone.templateml').error('Failed to generate template: %s %s\n%s' % (type(e), e, traceback.format_exc()) )
+ else:
+ logging.getLogger('cone.templateml').info('No (valid) templates found.')
+
+ def _encode_data(self, data, encoding, write_bom):
+ """
+ Encode the given data using the given encoding and BOM definition.
+ @param data: The data to encode.
+ @param encoding: The encoding to use.
+ @param write_bom: True or False to define whether the BOM should be written
+ for Unicode encodings, None for default.
+ """
+ data = data.encode(encoding)
+
+ # Check if we need to do special handling for BOM
+ if write_bom is not None:
+ BOM_MAPPING = {'utf-8' : codecs.BOM_UTF8,
+ 'utf-16' : codecs.BOM_UTF16,
+ 'utf-16-be' : codecs.BOM_UTF16_BE,
+ 'utf-16-le' : codecs.BOM_UTF16_LE}
+
+ # Use the name from a CodecInfo object to account for
+ # aliases (e.g. U8 and UTF-8 both map to utf-8)
+ codec_info = codecs.lookup(encoding)
+ if codec_info.name in BOM_MAPPING:
+ # Add or remove as necessary
+ BOM = BOM_MAPPING[codec_info.name]
+ if write_bom == True and not data.startswith(BOM):
+ data = BOM + data
+ elif write_bom == False and data.startswith(BOM):
+ data = data[len(BOM):]
+ return data
+
+
+class OutputFile(object):
+ def __init__(self):
+ self.filename = ''
+ self.path = ''
+ self.encoding = "utf-8"
+ self.template = TempFile()
+ self.filters = []
+ self.bom = None
+
+ def set_filename(self, filename):
+ self.filename = filename
+
+ def set_path(self, path):
+ self.path = path
+
+ def set_encoding(self, encoding):
+ self.encoding = encoding
+
+ def set_template(self, template):
+ self.template = template
+
+ def add_filter(self, filter):
+ self.filters.append(filters)
+
+ def set_filters(self, filters):
+ self.filters = filters
+
+ def __eq__(self, other):
+ if (self.template == other.template and self.encoding == other.encoding and self.path == other.path and self.filename == other.filename and self.filters == other.filters):
+ return True
+ return False
+
+ def __repr__(self):
+ return "OutputFile(filename=%r, path=%r, encoding=%r, template=%r, filters=%r" % (self.filename, self.path, self.encoding, self.template, self.filters)
+
+class TempFile(object):
+ def __init__(self):
+ self.template = ""
+ self.extensions = []
+ self.filters = []
+ self.path = ''
+
+ def set_path(self, path):
+ self.path = path
+
+ def set_template(self, template):
+ self.template = template
+
+ def add_extension(self, extension):
+ self.extensions.append(extension)
+
+ def add_filter(self, filter):
+ self.filters.append(filter)
+
+ def add_filter2(self, name, code):
+ self.filters.append(Filter(name, code))
+
+ def __eq__(self, other):
+ if self.template == other.template and self.filters == other.filters and self.extensions == other.extensions and self.path == other.path:
+ return True
+ return False
+
+class Filter(object):
+ def __init__(self, name, code):
+ self.name = name
+ self.code = code
+ self.path = None
+
+ def __init__(self):
+ self.name = None
+ self.code = None
+ self.path = None
+
+ def set_path(self, path):
+ self.path = path
+
+ def set_name(self, name):
+ self.name = name
+
+ def set_code(self, code):
+ self.code = code
+
+ def __eq__(self, other):
+ if self.name == other.name and self.code == other.code and self.path == other.path:
+ return True
+ return False
+
+class FeatureDictProxy(object):
+ """
+ Proxy class that behaves like a dictionary, but loads attributes from
+ the Feature object it proxies only when they are requested.
+ """
+ def __init__(self, feature):
+ self._feature = feature
+ self._children = {}
+
+ def _get_dict(self):
+ result = {
+ '_name' : self._feature.name,
+ '_namespace' : self._feature.namespace,
+ '_value' : self._feature.get_value(),
+ '_fqr' : self._feature.fqr,
+ '_type' : self._feature.type}
+ for ref, obj in self._children.iteritems():
+ result[ref] = obj
+ return result
+
+ def items(self):
+ return self._get_dict().items()
+
+ def iteritems(self):
+ return self._get_dict().iteritems()
+
+ def __getitem__(self, name):
+ if name == '_name': return self._feature.name
+ elif name == '_namespace': return self._feature.namespace
+ elif name == '_value': return self._feature.get_value()
+ elif name == '_fqr': return self._feature.fqr
+ elif name == '_type': return self._feature.type
+ else: return self._children[name]
+
+ def __setitem__(self, name, value):
+ self._children[name] = value
+
+ def __len__(self):
+ return len(self._get_dict())
+
+ def __eq__(self, other):
+ if not isinstance(other, dict):
+ return False
+ else:
+ return self._get_dict() == other
+
+ def __ne__(self, other):
+ return not (self == other)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_list.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_list.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,317 @@
+[
+{
+ '_fqr': 'Feature1',
+ '_name': 'Feature 1',
+ '_namespace': '',
+ '_type': None,
+ '_value': None,
+ 'BooleanSetting': {
+ '_fqr': 'Feature1.BooleanSetting',
+ '_name': 'Boolean setting',
+ '_namespace': 'Feature1',
+ '_type': 'boolean',
+ '_value': True,
+ },
+ 'FolderSetting': {
+ '_fqr': 'Feature1.FolderSetting',
+ '_name': 'Folder setting',
+ '_namespace': 'Feature1',
+ '_type': 'folder',
+ '_value': None,
+ 'localPath': {
+ '_fqr': 'Feature1.FolderSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': 'default_folder',
+ },
+ 'targetPath': {
+ '_fqr': 'Feature1.FolderSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': None,
+ },
+ },
+ 'IntSetting': {
+ '_fqr': 'Feature1.IntSetting',
+ '_name': 'Int setting',
+ '_namespace': 'Feature1',
+ '_type': 'int',
+ '_value': 10,
+ },
+ 'SequenceSetting': {
+ '_fqr': 'Feature1.SequenceSetting',
+ '_name': 'Sequence setting',
+ '_namespace': 'Feature1',
+ '_type': 'sequence',
+ '_value': [[['seq/file1.txt', None], 'false', 'item 1']],
+ 'BooleanSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.BooleanSubSetting',
+ '_name': 'Boolean sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'boolean',
+ '_value': ['false'],
+ },
+ 'FileSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting',
+ '_name': 'File sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'file',
+ '_value': [['seq/file1.txt', None]],
+ 'localPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': ['seq/file1.txt'],
+ },
+ 'targetPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': [None],
+ },
+ },
+ 'StringSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'string',
+ '_value': ['item 1'],
+ },
+ },
+ 'StringSetting': {
+ '_fqr': 'Feature1.StringSetting',
+ '_name': 'String setting',
+ '_namespace': 'Feature1',
+ '_type': 'string',
+ '_value': 'default string',
+ },
+ },
+{
+ '_fqr': 'Feature1.FolderSetting',
+ '_name': 'Folder setting',
+ '_namespace': 'Feature1',
+ '_type': 'folder',
+ '_value': None,
+ 'localPath': {
+ '_fqr': 'Feature1.FolderSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': 'default_folder',
+ },
+ 'targetPath': {
+ '_fqr': 'Feature1.FolderSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': None,
+ },
+ },
+{
+ '_fqr': 'Feature1.FolderSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': 'default_folder',
+ },
+{
+ '_fqr': 'Feature1.FolderSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': None,
+ },
+{
+ '_fqr': 'Feature1.IntSetting',
+ '_name': 'Int setting',
+ '_namespace': 'Feature1',
+ '_type': 'int',
+ '_value': 10,
+ },
+{
+ '_fqr': 'Feature1.StringSetting',
+ '_name': 'String setting',
+ '_namespace': 'Feature1',
+ '_type': 'string',
+ '_value': 'default string',
+ },
+{
+ '_fqr': 'Feature1.BooleanSetting',
+ '_name': 'Boolean setting',
+ '_namespace': 'Feature1',
+ '_type': 'boolean',
+ '_value': True,
+ },
+{
+ '_fqr': 'Feature1.SequenceSetting',
+ '_name': 'Sequence setting',
+ '_namespace': 'Feature1',
+ '_type': 'sequence',
+ '_value': [[['seq/file1.txt', None], 'false', 'item 1']],
+ 'BooleanSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.BooleanSubSetting',
+ '_name': 'Boolean sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'boolean',
+ '_value': ['false'],
+ },
+ 'FileSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting',
+ '_name': 'File sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'file',
+ '_value': [['seq/file1.txt', None]],
+ 'localPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': ['seq/file1.txt'],
+ },
+ 'targetPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': [None],
+ },
+ },
+ 'StringSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'string',
+ '_value': ['item 1'],
+ },
+ },
+{
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting',
+ '_name': 'File sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'file',
+ '_value': [['seq/file1.txt', None]],
+ 'localPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': ['seq/file1.txt'],
+ },
+ 'targetPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': [None],
+ },
+ },
+{
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': ['seq/file1.txt'],
+ },
+{
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': [None],
+ },
+{
+ '_fqr': 'Feature1.SequenceSetting.BooleanSubSetting',
+ '_name': 'Boolean sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'boolean',
+ '_value': ['false'],
+ },
+{
+ '_fqr': 'Feature1.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'string',
+ '_value': ['item 1'],
+ },
+{
+ '_fqr': 'Feature2',
+ '_name': 'Feature 2',
+ '_namespace': '',
+ '_type': None,
+ '_value': None,
+ 'SequenceSetting': {
+ '_fqr': 'Feature2.SequenceSetting',
+ '_name': 'Sequence setting',
+ '_namespace': 'Feature2',
+ '_type': 'sequence',
+ '_value': [['1', 'seq1 2 item 1']],
+ 'IntSubSetting': {
+ '_fqr': 'Feature2.SequenceSetting.IntSubSetting',
+ '_name': 'Int sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'int',
+ '_value': ['1'],
+ },
+ 'StringSubSetting': {
+ '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'string',
+ '_value': ['seq1 2 item 1'],
+ },
+ },
+ 'StringSetting': {
+ '_fqr': 'Feature2.StringSetting',
+ '_name': 'String setting',
+ '_namespace': 'Feature2',
+ '_type': 'string',
+ '_value': 'feature 2 string',
+ },
+ },
+{
+ '_fqr': 'Feature2.StringSetting',
+ '_name': 'String setting',
+ '_namespace': 'Feature2',
+ '_type': 'string',
+ '_value': 'feature 2 string',
+ },
+{
+ '_fqr': 'Feature2.SequenceSetting',
+ '_name': 'Sequence setting',
+ '_namespace': 'Feature2',
+ '_type': 'sequence',
+ '_value': [['1', 'seq1 2 item 1']],
+ 'IntSubSetting': {
+ '_fqr': 'Feature2.SequenceSetting.IntSubSetting',
+ '_name': 'Int sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'int',
+ '_value': ['1'],
+ },
+ 'StringSubSetting': {
+ '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'string',
+ '_value': ['seq1 2 item 1'],
+ },
+ },
+{
+ '_fqr': 'Feature2.SequenceSetting.IntSubSetting',
+ '_name': 'Int sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'int',
+ '_value': ['1'],
+ },
+{
+ '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'string',
+ '_value': ['seq1 2 item 1'],
+ },
+]
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_tree.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_tree.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,128 @@
+{
+ 'Feature1': {
+ '_fqr': 'Feature1',
+ '_name': 'Feature 1',
+ '_namespace': '',
+ '_type': None,
+ '_value': None,
+ 'BooleanSetting': {
+ '_fqr': 'Feature1.BooleanSetting',
+ '_name': 'Boolean setting',
+ '_namespace': 'Feature1',
+ '_type': 'boolean',
+ '_value': True,
+ },
+ 'FolderSetting': {
+ '_fqr': 'Feature1.FolderSetting',
+ '_name': 'Folder setting',
+ '_namespace': 'Feature1',
+ '_type': 'folder',
+ '_value': None,
+ 'localPath': {
+ '_fqr': 'Feature1.FolderSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': 'default_folder',
+ },
+ 'targetPath': {
+ '_fqr': 'Feature1.FolderSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.FolderSetting',
+ '_type': 'string',
+ '_value': None,
+ },
+ },
+ 'IntSetting': {
+ '_fqr': 'Feature1.IntSetting',
+ '_name': 'Int setting',
+ '_namespace': 'Feature1',
+ '_type': 'int',
+ '_value': 10,
+ },
+ 'SequenceSetting': {
+ '_fqr': 'Feature1.SequenceSetting',
+ '_name': 'Sequence setting',
+ '_namespace': 'Feature1',
+ '_type': 'sequence',
+ '_value': [[['seq/file1.txt', None], 'false', 'item 1']],
+ 'BooleanSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.BooleanSubSetting',
+ '_name': 'Boolean sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'boolean',
+ '_value': ['false'],
+ },
+ 'FileSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting',
+ '_name': 'File sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'file',
+ '_value': [['seq/file1.txt', None]],
+ 'localPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.localPath',
+ '_name': 'localPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': ['seq/file1.txt'],
+ },
+ 'targetPath': {
+ '_fqr': 'Feature1.SequenceSetting.FileSubSetting.targetPath',
+ '_name': 'targetPath',
+ '_namespace': 'Feature1.SequenceSetting.FileSubSetting',
+ '_type': 'string',
+ '_value': [None],
+ },
+ },
+ 'StringSubSetting': {
+ '_fqr': 'Feature1.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature1.SequenceSetting',
+ '_type': 'string',
+ '_value': ['item 1'],
+ },
+ },
+ 'StringSetting': {
+ '_fqr': 'Feature1.StringSetting',
+ '_name': 'String setting',
+ '_namespace': 'Feature1',
+ '_type': 'string',
+ '_value': 'default string',
+ },
+ },
+ 'Feature2': {
+ '_fqr': 'Feature2',
+ '_name': 'Feature 2',
+ '_namespace': '',
+ '_type': None,
+ '_value': None,
+ 'SequenceSetting': {
+ '_fqr': 'Feature2.SequenceSetting',
+ '_name': 'Sequence setting',
+ '_namespace': 'Feature2',
+ '_type': 'sequence',
+ '_value': [['1', 'seq1 2 item 1']],
+ 'IntSubSetting': {
+ '_fqr': 'Feature2.SequenceSetting.IntSubSetting',
+ '_name': 'Int sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'int',
+ '_value': ['1'],
+ },
+ 'StringSubSetting': {
+ '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
+ '_name': 'String sub-setting',
+ '_namespace': 'Feature2.SequenceSetting',
+ '_type': 'string',
+ '_value': ['seq1 2 item 1'],
+ },
+ },
+ 'StringSetting': {
+ '_fqr': 'Feature2.StringSetting',
+ '_name': 'String setting',
+ '_namespace': 'Feature2',
+ '_type': 'string',
+ '_value': 'feature 2 string',
+ },
+ },
+ }
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,104 @@
+
+
+
+ Feature with all setting types
+
+ A folder setting
+
+
+ A real setting
+
+
+ A file setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A folder sub-setting
+
+
+ A real sub-setting
+
+
+ A file sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+
+
+ default_folder
+ 3.14
+ default_file.txt
+ 10
+ John Doe
+ true
+ 1
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ false
+ 1
+
+
+ カタカナ
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/confml/feature2.confml
Binary file configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/confml/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/confml/output_define.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/confml/output_define.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ confmlref_filename.txt
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/access_configuration.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/access_configuration.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+Configuration name: {{ configuration.get_path() }}
+{% for feature in configuration.get_default_view().get_features('**') %}
+{{ feature.fqr }}
+{% endfor %}
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/external_tempfile.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/external_tempfile.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file1.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file1.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+ Description field text
+
+
+ ABC kissa kävelee
+
+
+
+
+
+
+
+ ABCD kissa kävelee
+
+
+
+
+
+ lambda a,b: a+b
+
+
+
+ ABCD kissa kävelee
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file2.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file2.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+ Description field text
+
+
+
+
+
+ lambda a,b: a+b
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file3.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file3.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+ Description field text
+
+
+ 'Hello {{ feat_tree.Feature1.StringSetting._value }}!'
+
+
+ lambda a,b: a+b
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file4.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file4.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+ Description field text
+
+
+ 'Hello {{ feat_tree.Feature1.StringSetting._value }}!'
+
+
+
+ 'Hello {{ feat_tree.Feature1.StringSetting._value }} again!'
+
+
+
+ 2+3={{ 2|test_filter(3) }}
+
+
+
+
+ --{{ 3|test_filter3(2) }}
+
+
+ lambda a,b: a+b
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file5.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file5.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ Description field text
+
+
+ 'Hello {{ feat_tree.Feature1.StringSetting._value }}'
+
+ lambda a,b: a+b
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file6.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file6.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+
+
+ Description field text
+
+
+ 'Hello {{ feat_tree.Feature1._name }} {{ feat_tree.Feature1.StringSetting._value }} {{ feat_tree.Feature1.SequenceSetting.RealSubSetting._value }}!'
+
+
+
+ {% for feature in feat_list %}
+ {{ feature._fqr }}:{{ feature._value }}
+{% endfor %}
+
+
+ lambda a,b: a+b
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ Description field text
+
+
+
+Features in list
+{% for feat in feat_list %}
+ Feature: {{feat._name}} value: {{feat._value}}
+{% endfor %}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test2.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test2.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+
+
+ Description field text
+
+
+
+Value of Feature1.UnicodeValueSetting: {{ feat_tree.Feature1.UnicodeValueSetting._value }}
+Value of Feature1.StringSetting1: {{ feat_tree.Feature1.StringSetting1._value }}
+Value of Feature2: {{ feat_tree.Feature2._value }}
+Value of Feature2.set1.sub1: {{ feat_tree.Feature2.set1.sub1._value }}
+Value of Feature2.set1.sub2: {{ feat_tree.Feature2.set1.sub2 }}
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test3.template
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test3.template Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+Value of Feature1.UnicodeValueSetting: {{ feat_tree.Feature1.UnicodeValueSetting._value }}
+Value of Feature1.StringSetting1: {{ feat_tree.Feature1.StringSetting1._value }}
+Value of Feature2: {{ feat_tree.Feature2._value }}
+Value of Feature2.set1.sub1: {{ feat_tree.Feature2.set1.sub1._value }}
+Value of Feature2.set1.sub2: {{ feat_tree.Feature2.set1.sub2 }}
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test3.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/has_ref_template_test3.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+ Description field text
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/output_with_ref.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/output_with_ref.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+Configuration name: {{ configuration.get_path() }}
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/unicode_template_test.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/unicode_template_test.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ Description field text
+
+
+ {# -#}
+Value of Feature1.UnicodeValueSetting: {{ feat_tree.Feature1.UnicodeValueSetting._value }}
+Unicode from template: ελληνικά
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/utf_bom_test.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/utf_bom_test.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+
+
+ 100€
+
+ 100€
+ 100€
+ 100€
+ 100€
+ 100€
+
+ 100€
+ 100€
+ 100€
+ 100€
+ 100€
+
+ 100€
+ 100€
+ 100€
+ 100€
+ 100€
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/assets/s60/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/assets/s60/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test/confml/test_features.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test/confml/test_features.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ default_folder
+ 10
+ default string
+ true
+
+
+ seq/default_file.txt
+ template
+ false
+
+
+ seq/file1.txt
+ item 1
+ false
+
+
+
+
+ feature 2 string
+
+
+ template
+ 0
+
+
+ seq1 2 item 1
+ 1
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test/implml/test.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test/implml/test.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+
+
+ Description field text
+
+
+ 'Hello {{ feat_tree.Feature1._name }} {{ feat_tree.Feature1.StringSetting._value }} {{ feat_tree.Feature1.SequenceSetting.RealSubSetting._value }}!'
+
+
+
+ {% for feature in feat_list %}
+ {{ feature._fqr }}:{{ feature._value }}
+{% endfor %}
+
+
+ lambda a,b: a+b
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/create_dict_test/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/family/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/family/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/family/product/root.confml
Binary file configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/family/product/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/family/root.confml
Binary file configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/family/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/filter.filter
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/filter.filter Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+lambda a,b: a-b
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/filter.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/filter.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+lambda a,b: a-b
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/test_filter.filter
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/test_filter.filter Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+lambda a,b: a-b
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/test_filter3.filter
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/filters/test_filter3.filter Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+lambda a,b: a*b
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/product.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/product.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/root1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/root1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/templates/template.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/templates/template.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+include AABBCC
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/templates/template.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/templates/template.xml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+include xml AABBCC
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/templates/template2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/templates/template2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+2+3={{ 2|test_filter(3) }}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/unittest_templatemlplugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/unittest_templatemlplugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,675 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil, sys
+
+try:
+ from cElementTree import ElementTree, ElementInclude
+except ImportError:
+ try:
+ from elementtree import ElementTree, ElementInclude
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+from templatemlplugin import templatemlplugin
+from types import NoneType
+from testautomation.base_testcase import BaseTestCase
+from testautomation.utils import hex_to_bindata
+
+from cone.public import exceptions,plugin,api,utils
+from cone.storage import filestorage
+from cone.confml import implml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'project')
+
+TEMPML_DOC1 = " " \
+ "" \
+ "Desc " \
+ "" \
+ "ABCDF " \
+ " " \
+ "lambda a,b: a+b " \
+ " "
+
+TEMPML_DOC2 = " " \
+ "" \
+ "Desc " \
+ "" \
+ " " \
+ " " \
+ "lambda a,b: a+b " \
+ " "
+
+TEMPML_DOC3 = " " \
+ "" \
+ "Desc " \
+ "" \
+ " " \
+ " " \
+ "lambda a,b: a+b " \
+ " "
+
+TEMPML_DOC4 = " " \
+ "" \
+ "" \
+ "" \
+ " " \
+ "" \
+ " "
+
+TEMPML1 = "" \
+ "ABCDF " \
+ " "
+
+TEMPML2 = "" \
+ "" \
+ "include AABBCC" \
+ " " \
+ " "
+
+TEMPML3 = "" \
+ "" \
+ "include AABBCC" \
+ " " \
+ "lambda a,b: a+b " \
+ " "
+
+TEMPML4 = "" \
+ "" \
+ "" \
+ " "
+
+
+def impl_from_resource(resource_ref, configuration):
+ doc_root = plugin.ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
+ readers = { templateml.TemplatemlImplReader.NAMESPACE: templateml.TemplatemlImplReader }
+ ns = utils.xml.split_tag_namespace(doc_root.tag)[0]
+ if ns in readers:
+ return readers[ns].read_impl(resource_ref, configuration, doc_root)
+ else:
+ return None
+
+class TestTemplatemlPlugin(BaseTestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = os.path.join(ROOT_PATH, 'output')
+ os.chdir(os.path.join(ROOT_PATH))
+
+ def tearDown(self):
+ os.chdir(self.curdir)
+
+ def load_config(self, config):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ return p.get_configuration(config)
+
+ def load_impl(self, resource_ref, config='root1.confml'):
+ configuration = self.load_config(config)
+ pattern = '^' + resource_ref.replace('.', r'\.') + '$'
+ impls = plugin.get_impl_set(configuration, pattern)
+ impls.output = self.output
+ impl_list = impls.get_implementations_by_file(resource_ref)
+ self.assertEquals(1, len(impl_list))
+ return impl_list[0]
+
+ def test_parse_desc(self):
+ impl = self.load_impl('Layer1/implml/file1.templateml')
+ self.assertEqual("Description field text", impl.reader.desc)
+
+ def test_parse_output_with_file_ref(self):
+ impl = self.load_impl('Layer1/implml/output_with_ref.templateml')
+ self.assertEquals(impl.list_output_files(), [os.path.normpath('output/confmlref_filename.txt')])
+
+ def test_parse_outputs(self):
+ impl = self.load_impl('Layer1/implml/file1.templateml')
+ outputs = []
+ output1 = templatemlplugin.OutputFile()
+ output1.set_encoding("UTF-16")
+ output1.set_filename("test.txt")
+ output1.set_path('')
+ temp1 = templatemlplugin.TempFile()
+ temp1.set_template(u'ABC kissa k\xe4velee')
+ output1.set_template(temp1)
+ outputs.append(output1)
+
+ output2 = templatemlplugin.OutputFile()
+ output2.set_encoding("UTF-16")
+ output2.set_filename("test2.txt")
+ output2.set_path("output")
+ temp2 = templatemlplugin.TempFile()
+ temp2.set_template('AABBCC')
+ output2.set_template(temp2)
+ outputs.append(output2)
+
+ output3 = templatemlplugin.OutputFile()
+ output3.set_encoding("UTF-8")
+ output3.set_filename("test3.txt")
+ output3.set_path('')
+ temp3 = templatemlplugin.TempFile()
+ temp3.set_template(u'ABC kissa k\xe4velee')
+ output3.set_template(temp3)
+
+ outputs.append(output3)
+
+ self.assertNotEqual(impl.reader.outputs, None)
+ self.assertEqual(outputs[0].encoding, impl.reader.outputs[0].encoding)
+ self.assertEqual(outputs[0].filename, impl.reader.outputs[0].filename)
+ self.assertEqual(outputs[0].path, impl.reader.outputs[0].path)
+ self.assertEqual(outputs[0].template.template, impl.reader.outputs[0].template.template)
+ self.assertEqual(outputs[0].template.extensions, impl.reader.outputs[0].template.extensions)
+ self.assertEqual(outputs[0].template.filters, impl.reader.outputs[0].template.filters)
+ self.assertEqual(outputs[0].template, impl.reader.outputs[0].template)
+ self.assertEqual(outputs[0], impl.reader.outputs[0])
+
+ self.assertEqual(outputs[1].encoding, impl.reader.outputs[1].encoding)
+ self.assertEqual(outputs[1].filename, impl.reader.outputs[1].filename)
+ self.assertEqual(outputs[1].path, impl.reader.outputs[1].path)
+ #self.assertEqual(outputs[1].template.template, impl.reader.outputs[1].template.template)
+ self.assertEqual(outputs[1].template.extensions, impl.reader.outputs[1].template.extensions)
+ self.assertEqual(outputs[1].template.filters, impl.reader.outputs[1].template.filters)
+ #self.assertEqual(outputs[1].template, impl.reader.outputs[1].template)
+ #self.assertEqual(outputs[1], impl.reader.outputs[1])
+
+ self.assertEqual(outputs[2].encoding, impl.reader.outputs[2].encoding)
+ self.assertEqual(outputs[2].filename, impl.reader.outputs[2].filename)
+ self.assertEqual(outputs[2].path, impl.reader.outputs[2].path)
+ #self.assertEqual(outputs[2].template.template, impl.reader.outputs[2].template.template)
+ self.assertEqual(outputs[2].template.extensions, impl.reader.outputs[2].template.extensions)
+ self.assertEqual(outputs[2].template.filters, impl.reader.outputs[2].template.filters)
+ #self.assertEqual(outputs[2].template, impl.reader.outputs[2].template)
+
+ #self.assertEqual(outputs[2], impl.reader.outputs[2])
+
+ def test_parse_outputfile(self):
+ output1 = templatemlplugin.OutputFile()
+ output2 = templatemlplugin.OutputFile()
+
+ self.assertEqual(output1, output2)
+ self.assertEqual(output1.encoding, output2.encoding)
+ self.assertEqual(output1.path, output2.path)
+ self.assertEqual(output1.filename, output2.filename)
+
+ output1.set_encoding("utf-8")
+ output2.set_encoding("utf-8")
+
+ self.assertEqual(output1, output2)# utf-8, utf-8
+
+ output1.set_encoding("utf-16")
+
+ self.assertNotEqual(output1, output2)#utf-16, utf-8
+
+ output2.set_encoding("utf-16")
+
+ self.assertEqual(output1, output2)#utf-16, utf-16
+
+ def test_parse_template(self):
+ reader = templatemlplugin.TemplatemlImplReader()
+ reader.fromstring(TEMPML_DOC1)
+
+ temp1 = reader.parse_template(ElementTree.fromstring(TEMPML1))
+ temp2 = templatemlplugin.TempFile()
+ temp2.set_template("ABCDF")
+
+ self.assertEqual(temp1.template, temp2.template)
+ self.assertEqual(temp1.extensions, temp2.extensions)
+ self.assertEqual(temp1.filters, temp2.filters)
+ self.assertEqual(temp1, temp2)
+
+ def test_parse_template_from_xinclude(self):
+ try:
+ reader = templatemlplugin.TemplatemlImplReader()
+ reader.fromstring(TEMPML_DOC2)
+
+ temp1 = reader.parse_template(ElementTree.fromstring(TEMPML2))
+ temp2 = templatemlplugin.TempFile()
+ temp2.set_template("include AABBCC")
+ except exceptions.ParseError, e:
+ self.fail("Known bug: ticket #2007")
+
+ self.assertEqual(temp1.template, temp2.template)
+ self.assertEqual(temp1.extensions, temp2.extensions)
+ self.assertEqual(temp1.filters, temp2.filters)
+ self.assertEqual(temp1, temp2)
+
+ def test_parse_template_filter(self):
+ try:
+ reader = templatemlplugin.TemplatemlImplReader()
+ reader.fromstring(TEMPML_DOC3)
+ filters1 = reader.filters
+ filter2 = templatemlplugin.Filter()
+ filter2.set_code("lambda a,b: a+b")
+ filter2.set_name("test_filter")
+ except exceptions.ParseError, e:
+ self.fail( "Known bug: ticket #2007")
+ self.assertEqual(filters1[0].name, filter2.name)
+ self.assertEqual(filters1[0].code, filter2.code)
+ self.assertEqual(filters1[0], filter2)
+
+ def test_parse_template_filter(self):
+ class DummyConfiguration(object):
+ def get_resource(self, ref):
+ class DummyResource(object):
+ def read(self): return ''
+ def close(self): return None
+ return DummyResource()
+ def get_default_view(self): return None
+ reader = templatemlplugin.TemplatemlImplReader('foo/implml/bar.implml', DummyConfiguration())
+ reader.fromstring(TEMPML_DOC4)
+
+ filters1 = reader.filters
+ filter2 = templatemlplugin.Filter()
+ filter2.set_code(None)
+ filter2.set_name("test_filter")
+ filter2.set_path("../../filter/filter.py")
+ temp1 = reader.parse_template(ElementTree.fromstring(TEMPML4))
+ temp2 = templatemlplugin.TempFile()
+ temp2.set_template('')
+ temp2.set_path('')
+
+ self.assertEqual(filters1[0].name, filter2.name)
+ self.assertEqual(filters1[0].code, filter2.code)
+ self.assertEqual(filters1[0].path, filter2.path)
+ self.assertEqual(filters1[0], filter2)
+ self.assertEqual(temp1.template, temp2.template)
+ self.assertEqual(temp1.extensions, temp2.extensions)
+ self.assertEqual(temp1.filters, temp2.filters)
+ self.assertEqual(temp1, temp2)
+
+ def test_simple_generate_prj(self):
+
+ self.remove_if_exists(os.path.normpath("output/output/test.txt"))
+
+ impl = self.load_impl('Layer1/implml/file2.templateml')
+ #impl.context = {'name' : 'some value'}
+ impl.generate()
+
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test.txt")))
+ result_file = None
+ try:
+ result_file = open(os.path.normpath("output/output/test.txt"))
+ for line in result_file:
+ self.assertTrue(line == "include AABBCC")
+ finally:
+ if result_file != None: result_file.close()
+
+ def test_simple_generate_prj3(self):
+
+ self.remove_if_exists(os.path.normpath("output/output/test3.txt"))
+
+ impl = self.load_impl('Layer1/implml/file3.templateml')
+ impl.generate()
+
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test3.txt")))
+ result_file = None
+ try:
+ result_file = open(os.path.normpath("output/output/test3.txt"))
+ for line in result_file:
+ self.assertTrue(line == "'Hello John Doe!'")
+ finally:
+ if result_file != None: result_file.close()
+
+ def test_simple_generate_prj4_with_filters(self):
+
+ self.remove_if_exists(os.path.normpath("output/output/test4a.txt"))
+ self.remove_if_exists(os.path.normpath("output/output/test4b.txt"))
+ self.remove_if_exists(os.path.normpath("output/output/test4c.txt"))
+ self.remove_if_exists(os.path.normpath("output/output/test4d.txt"))
+
+ impl = self.load_impl('Layer1/implml/file4.templateml')
+ #impl.context = {'name' : 'John Doe'}
+ impl.generate()
+
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test4a.txt")))
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test4b.txt")))
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test4c.txt")))
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test4d.txt")))
+
+ result_file1 = None
+ result_file2 = None
+ result_file3 = None
+ result_file4 = None
+
+ try:
+ result_file1 = open(os.path.normpath("output/output/test4a.txt"))
+ result_file2 = open(os.path.normpath("output/output/test4b.txt"))
+ result_file3 = open(os.path.normpath("output/output/test4c.txt"))
+ result_file4 = open(os.path.normpath("output/output/test4d.txt"))
+
+ if result_file1 != None:
+ for line in result_file1:
+ self.assertTrue(line == "'Hello John Doe!'")
+ else:
+ self.fail("No result file found: output/output/test4a.txt")
+
+ if result_file2 != None:
+ for line in result_file2:
+ self.assertTrue(line == "'Hello John Doe again!'")
+ else:
+ self.fail("No result file found: output/output/test4b.txt")
+
+ if result_file3 != None:
+ for line in result_file3:
+ self.assertTrue(line == "2+3=5")
+ else:
+ self.fail("No result file found: output/output/test4c.txt")
+
+ if result_file4 != None:
+ for line in result_file4:
+ self.assertTrue(line == "--6")
+ else:
+ self.fail("No result file found: output/output/test4d.txt")
+
+ finally:
+ if result_file1 != None: result_file1.close()
+ if result_file2 != None: result_file2.close()
+ if result_file3 != None: result_file3.close()
+ if result_file4 != None: result_file4.close()
+
+ def test_simple_generate_prj_extfiles_with_filters(self):
+
+ self.remove_if_exists(os.path.normpath("output/output/test_ext_temp_file.txt"))
+
+ impl = self.load_impl('Layer1/implml/external_tempfile.templateml')
+
+ impl.generate()
+
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test_ext_temp_file.txt")))
+
+ result_file1 = None
+
+ try:
+ result_file1 = open(os.path.normpath("output/output/test_ext_temp_file.txt"))
+ lines = 0
+
+ if result_file1 != None:
+ for line in result_file1:
+ self.assertTrue(line == "2+3=-1")
+ lines += 1
+ else:
+ self.fail("No result file found: output/output/test_ext_temp_file.txt")
+
+ self.assertTrue(lines == 1, "Wrong number of lines generated.")
+
+ finally:
+ if result_file1 != None: result_file1.close()
+
+ def test_generate_prj1(self):
+
+ self.remove_if_exists(os.path.normpath("output/output/test5a.txt"))
+
+ impl = self.load_impl('Layer1/implml/file5.templateml')
+ impl.generate()
+ self.assertTrue(os.path.exists(os.path.normpath("output/output/test5a.txt")))
+
+ result_file1 = None
+ try:
+ result_file1 = open(os.path.normpath("output/output/test5a.txt"))
+
+ if result_file1 != None:
+ for line in result_file1:
+ self.assertTrue(line == "'Hello John Doe'")
+ else:
+ self.fail("No result file found: output/output/test5a.txt")
+ finally:
+ if result_file1 != None: result_file1.close()
+
+ def test_generate_access_configuration(self):
+
+ self.remove_if_exists(os.path.normpath("output/access_configuration.txt"))
+
+ impl = self.load_impl('Layer1/implml/access_configuration.templateml')
+ impl.generate()
+ self.assertTrue(os.path.exists(os.path.normpath("output/access_configuration.txt")))
+
+ result_file1 = None
+ try:
+ result_file1 = open(os.path.normpath("output/access_configuration.txt"))
+ data = result_file1.read()
+ if result_file1 != None:
+ self.assertTrue(data.startswith("Configuration name: root1.confml"))
+ else:
+ self.fail("No result file found: output/access_configuration.txt")
+ finally:
+ if result_file1 != None: result_file1.close()
+
+ def test_create_context_dict1(self):
+ impl = self.load_impl('Layer1/implml/file6.templateml')
+ impl.context = impl.create_dict()
+ impl.generate()
+
+ def test_list_output_files(self):
+ impl = self.load_impl('Layer1/implml/file1.templateml')
+ impl.set_output_root('outdir')
+ output_files = impl.list_output_files()
+ expected = map(lambda n: os.path.normpath(n), [
+ 'outdir/test.txt',
+ 'outdir/output/test2.txt',
+ 'outdir/test3.txt',
+ 'outdir/output/test4.txt',
+ 'outdir/some/test/path/test5.txt',
+ ])
+ self.assertEquals(sorted(output_files), sorted(expected))
+
+ def test_has_ref(self):
+ impl = self.load_impl('Layer1/implml/has_ref_template_test2.templateml')
+ self.assertEquals(impl.has_ref('Feature1.StringSetting_not_found'), False)
+ self.assertEquals(impl.has_ref('Feature1.StringSetting1'), True)
+ self.assertEquals(impl.has_ref('Feature2'), True)
+ self.assertEquals(impl.has_ref('Feature2.set1.sub1'), True)
+ self.assertEquals(impl.has_ref('Feature2.set1.sub2'), True)
+ self.assertEquals(impl.has_ref('Feature1.UnicodeValueSetting'), True)
+
+ def test_has_ref_external_template(self):
+ impl = self.load_impl('Layer1/implml/has_ref_template_test3.templateml')
+ self.assertEquals(impl.has_ref('Feature1.StringSetting_not_found'), False)
+ self.assertEquals(impl.has_ref('Feature1.StringSetting1'), True)
+ self.assertEquals(impl.has_ref('Feature2'), True)
+ self.assertEquals(impl.has_ref('Feature2.set1.sub1'), True)
+ self.assertEquals(impl.has_ref('Feature2.set1.sub2'), True)
+ self.assertEquals(impl.has_ref('Feature1.UnicodeValueSetting'), True)
+
+ def test_has_ref_with_featree(self):
+ impl = self.load_impl('Layer1/implml/has_ref_template_test.templateml')
+ self.assertEquals(impl.has_ref('Feature1.StringSetting'), True)
+ self.assertEquals(impl.has_ref('Feature2.StringSetting'), True)
+
+ def test_unicode_in_template_and_value(self):
+ OUTPUT_DIR = os.path.join(ROOT_PATH, 'output', 'unicode_test')
+ self.remove_if_exists(OUTPUT_DIR)
+
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('root1.confml')
+ impls = plugin.get_impl_set(config,'unicode_template_test\.templateml$')
+ impls.output = OUTPUT_DIR
+ impls.generate()
+ self.assert_exists_and_contains_something(os.path.join(OUTPUT_DIR, "unicode_template_test.txt"))
+
+ # Check that the output exists and contains expected lines
+ f = open(os.path.join(OUTPUT_DIR, "unicode_template_test.txt"), "rb")
+ try: data = f.read().decode('utf-8')
+ finally: f.close()
+ self.assertTrue(data.find(u'Value of Feature1.UnicodeValueSetting: カタカナ') != -1)
+ self.assertTrue(data.find(u'Unicode from template: ελληνικά') != -1)
+
+ def test_create_context_dict_and_list(self):
+ config = self.load_config('create_dict_test.confml')
+ impls = plugin.get_impl_set(config, r'^create_dict_test/implml/test\.templateml$')
+ self.assertEquals(1, len(impls))
+ impl = iter(impls).next()
+ context = impl.create_dict()
+ feat_tree = context['feat_tree']
+ feat_list = context['feat_list']
+ self.assertEqual(context['configuration'], config)
+
+ # Check the created dictionary
+ expected_tree_file = os.path.join(ROOT_PATH, 'create_dict_test', 'expected_tree.txt')
+ expected_tree = eval(self.read_data_from_file(expected_tree_file).replace('\r', ''))
+ if feat_tree != expected_tree:
+ dir = os.path.join(ROOT_PATH, "temp", "create_dict_test", "tree")
+ self.create_dir(dir)
+ filename = os.path.join(dir, "expected.txt")
+ self.write_data_to_file(filename, self.feature_tree_to_str(expected_tree))
+ filename = os.path.join(dir, "actual.txt")
+ self.write_data_to_file(filename, self.feature_tree_to_str(feat_tree))
+ self.fail("Feature tree is not what was expected, see the files in '%s'" % dir)
+
+ # Check the created list
+ expected_list_file = os.path.join(ROOT_PATH, 'create_dict_test', 'expected_list.txt')
+ expected_list = eval(self.read_data_from_file(expected_list_file).replace('\r', ''))
+ if feat_list != expected_list:
+ dir = os.path.join(ROOT_PATH, "temp", "create_dict_test", "list")
+ self.create_dir(dir)
+ filename = os.path.join(dir, "expected.txt")
+ self.write_data_to_file(filename, self.feature_list_to_str(expected_list))
+ filename = os.path.join(dir, "actual.txt")
+ self.write_data_to_file(filename, self.feature_list_to_str(feat_list))
+ self.fail("Feature tree is not what was expected, see the files in '%s'" % dir)
+
+ def feature_tree_to_str(self, d, indent_amount=0):
+ """
+ Pretty-print a feature tree dictionary into a string.
+ """
+ INDENT_AMOUNT = 4
+ indent = indent_amount * ' '
+ temp = ['{']
+ if len(d) > 0: temp.append('\n')
+
+ indent += (INDENT_AMOUNT + indent_amount) * ' '
+
+ # Function for sorting the dict contents so that keys starting with
+ # '_' are first
+ def key_func(key_and_value):
+ key = key_and_value[0]
+ if key.startswith('_'): return '\x00' + key
+ else: return key
+
+ for key, value in sorted(d.items(), key=key_func):
+ temp.append(indent)
+ if isinstance(value, dict):
+ temp.append("%r: %s," % (key, self.feature_tree_to_str(value, indent_amount + INDENT_AMOUNT)))
+ else:
+ temp.append("%r: %r," % (key, value))
+ temp.append('\n')
+
+ if len(d) > 0: temp.append(indent)
+ temp.append('}')
+ return ''.join(temp)
+
+ def feature_list_to_str(self, lst):
+ """
+ Pretty-print a feature list into a string.
+ """
+ temp = ['[\n']
+ for item in lst:
+ if isinstance(item, dict): temp.append(self.feature_tree_to_str(item))
+ else: temp.append(repr(item))
+ temp.append(',\n')
+ temp.append(']')
+ return ''.join(temp)
+
+
+ def test_utf_bom_support(self):
+ OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/utf_bom_test')
+ self.recreate_dir(OUTPUT_DIR)
+ impl = self.load_impl('Layer1/implml/utf_bom_test.templateml')
+ impl.set_output_root(OUTPUT_DIR)
+ impl.generate()
+
+ def check(file, contents):
+ FILE = os.path.join(OUTPUT_DIR, file)
+ self.assert_file_content_equals(FILE, contents)
+
+ h = hex_to_bindata
+
+ # The all-around default should be UTF-8 without BOM
+ check('default.txt', h('31 30 30 E282AC'))
+
+ check('iso_8859_15_default.txt', h('31 30 30 A4'))
+ check('utf8_default.txt', h('31 30 30 E282AC'))
+ check('utf16be_default.txt', h('0031 0030 0030 20AC'))
+ check('utf16le_default.txt', h('3100 3000 3000 AC20'))
+
+ check('iso_8859_15_no_bom.txt', h('31 30 30 A4'))
+ check('utf8_no_bom.txt', h('31 30 30 E282AC'))
+ check('utf16be_no_bom.txt', h('0031 0030 0030 20AC'))
+ check('utf16le_no_bom.txt', h('3100 3000 3000 AC20'))
+
+ check('iso_8859_15_with_bom.txt', h('31 30 30 A4'))
+ check('utf8_with_bom.txt', h('EFBBBF 31 30 30 E282AC'))
+ check('utf16be_with_bom.txt', h('FEFF 0031 0030 0030 20AC'))
+ check('utf16le_with_bom.txt', h('FFFE 3100 3000 3000 AC20'))
+
+ if sys.byteorder == 'little':
+ check('utf16_default.txt', h('FFFE 3100 3000 3000 AC20'))
+ check('utf16_no_bom.txt', h('3100 3000 3000 AC20'))
+ check('utf16_with_bom.txt', h('FFFE 3100 3000 3000 AC20'))
+ else:
+ check('utf16_default.txt', h('FEFF 0031 0030 0030 20AC'))
+ check('utf16_no_bom.txt', h('0031 0030 0030 20AC'))
+ check('utf16_with_bom.txt', h('FEFF 0031 0030 0030 20AC'))
+
+ def test_invalid_encoding(self):
+ DATA = """
+
+ foo
+ """
+ reader = templatemlplugin.TemplatemlImplReader()
+ self.assertRaises(exceptions.ParseError, reader.fromstring, DATA)
+
+
+class TestExtractRefsFromTemplate(unittest.TestCase):
+ def test_extract_refs_from_template(self):
+ def t(data, expected_refs):
+ actual_refs = templatemlplugin.TemplatemlImpl._extract_refs_from_template(data)
+ self.assertEquals(expected_refs, actual_refs)
+
+ t("some text {{ feat_tree.Foo }} more text",
+ ['Foo'])
+ t("some text {{ feat_tree.Foo.Bar }} more text",
+ ['Foo.Bar'])
+ t("some text {{feat_tree.Foo.Bar}} more text",
+ ['Foo.Bar'])
+ t("some text {{ feat_tree.Foo.Bar.Baz }} more text",
+ ['Foo.Bar.Baz'])
+ t("some text {{ feat_tree.Foo.Bar.Baz._value }} more text",
+ ['Foo.Bar.Baz'])
+ t(u"some text {{ feat_tree.ударениÑ.ελληνικά }} more text",
+ [u'ударениÑ.ελληνικά'])
+ t(u"some text {{ feat_tree.ударениÑ.ελληνικά._value }} more text",
+ [u'ударениÑ.ελληνικά'])
+ t("some text {{ feat_tree.MyFeature.MySetting|some_filter }} more text",
+ ['MyFeature.MySetting'])
+ t(u"some text {{ feat_tree.MyFeature.MySetting|some_filter }} more text",
+ ['MyFeature.MySetting'])
+ t("some text {{ feat_tree.MyFeature.MySetting | some_filter }} more text",
+ ['MyFeature.MySetting'])
+ t("some text {{ feat_tree.MyFeature.MySetting._value|some_filter }} more text",
+ ['MyFeature.MySetting'])
+ t("some text {{ feat_tree.Xyz.Zyx._type }} more {{feat_tree.Xyz.Zyx._type}} text",
+ ['Xyz.Zyx', 'Xyz.Zyx'])
+ t("some text {% for x in feat_tree.MyFeature.MySetting._value|sort %} more text",
+ ['MyFeature.MySetting'])
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/dep-eggs/readme.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/dep-eggs/readme.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+This directory contains all library dependencies needed by any of the plug-ins as egg files.
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../..'))
+assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
+
+# Import plugin_utils from the plug-in sources root
+if PLUGIN_SOURCE_ROOT not in sys.path: sys.path.append(PLUGIN_SOURCE_ROOT)
+import plugin_utils
+
+# Run integration test initialization
+plugin_utils.integration_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/files_from_copy_list/file1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/files_from_copy_list/file1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/files_from_copy_list/file2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/files_from_copy_list/file2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test2
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/files_from_copy_list/file3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/files_from_copy_list/file3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test3
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/overlay_folder/overlay.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/overlay_folder/overlay.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+overlay
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/unicode_template_test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/expected/content/unicode_template_test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+Value of Feature1.StringSetting: カタカナ カタカナ <&> (from rule: カタカナ)
+Unicode from template: ελληνικά
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/.project
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/.project Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+ test_project
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerBuilder
+
+
+
+
+ com.nokia.s60ct.build.CenRepBuilder
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerNature
+ com.nokia.s60ct.build.CenRepNature
+ com.nokia.s60ct.build.CenRepNature
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/basic_setting_types_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/basic_setting_types_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+
+
+
+ Feature with basic setting types (ConfML v2.0)
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/empty_sequence.confml
Binary file configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/empty_sequence.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/feature2.confml
Binary file configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/file_folder_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/file_folder_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+
+
+
+ Feature with file and folder setting types
+
+ A folder setting
+
+
+
+
+ A file setting
+
+
+
+
+
+
+
+ default_folder
+ default_target_folder/
+
+
+ default_file.txt
+ default_target_folder/default_file_renamed.txt
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/sequence_setting_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/confml/sequence_setting_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,71 @@
+
+
+
+ Feature with a sequence setting (ConfML v2.0)
+
+ A sequence setting
+
+ A folder sub-setting
+
+
+
+
+ A real sub-setting
+
+
+ A file sub-setting
+
+
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ false
+ 1
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/base/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/confml/custom.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/confml/custom.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,86 @@
+
+
+
+ Settings for configuring the base layer's settings via rules and other implementation files on this layer
+
+
+ Sets whether the feature BitmaskTest is configured with pre-defined values
+
+
+
+ Sequence for listing files to be copied
+
+ The file to copy
+
+
+
+
+
+
+ The folder used for generating an .mbm file
+
+
+
+
+
+ The folder used for generating a .mif file
+
+
+
+
+
+ Sound file.
+
+
+
+
+
+ Sound folder.
+
+
+
+
+
+
+
+ Folder containing themes
+
+
+
+
+
+ TPF file for theme 1
+
+
+
+
+
+ TPF file for theme 2
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+ default.mp3
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/confml/view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/confml/view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,30 @@
+
+
+
+ Testing view
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/content/overlay/overlay_folder/overlay.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/content/overlay/overlay_folder/overlay.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+overlay
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/overlay.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/overlay.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/sequence_files.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/sequence_files.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+ True configures Feature1.StringSetting = Feature1.StringSetting + " " + BasicSettingTypesTest.StringSetting + u" (from rule: カタカナ)"
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/unicode_template_test.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/unicode_template_test.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ Description field text
+
+
+ {# -#}
+Value of Feature1.StringSetting: {{ feat_tree.Feature1.StringSetting._value }}
+Unicode from template: ελληνικά
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+
+
+
+
+ 555
+ カタカナ <&>
+
+
+ file1.txt
+ file2.txt
+ file3.txt
+
+
+
+
+ seq/default_folder
+ 10.10
+ seq/default_file.txt
+ 120
+ <&カタカナ>
+ true
+ 2
+
+
+
+
+ カタカナ
+
+ 1.5
+ 256
+ test
+ true
+ 1
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/content/file1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/content/file1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/content/file2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/content/file2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test2
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/content/file3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/content/file3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test3
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/data/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/testdata/generate/project/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/integration-test/unittest_generate.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/unittest_generate.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,87 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Lasse Salo
+
+import sys, os, shutil, unittest
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation import zip_dir
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+if sys.platform == "win32":
+ CONE_SCRIPT = "cone.cmd"
+else:
+ CONE_SCRIPT = "cone.sh"
+
+def get_cmd(action='generate'):
+ """Return the command used to run the ConE sub-action"""
+ if 'CONE_PATH' in os.environ:
+ CONE_CMD = os.path.join(os.environ['CONE_PATH'], CONE_SCRIPT)
+ if not os.path.exists(CONE_CMD):
+ raise RuntimeError("'%s' does not exist!" % CONE_CMD)
+ return '"%s" %s' % (CONE_CMD, action)
+ else:
+ SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+ assert os.path.split(SOURCE_ROOT)[1] == 'source'
+ cmd = 'python "%s" %s' % (os.path.normpath(os.path.join(SOURCE_ROOT, 'scripts/cone_tool.py')), action)
+ return cmd
+
+class TestCommonGenerateAllImplsOnLastLayer(BaseTestCase):
+
+ def _prepare_workdir(self, workdir):
+ workdir = os.path.join(ROOT_PATH, workdir)
+ self.recreate_dir(workdir)
+
+ # Any needed extra preparation can be done here
+
+ return workdir
+
+ def test_generate_all_impls_on_last_layer_on_file_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
+ self.assert_exists_and_contains_something(project_dir)
+ self._run_test_generate_all_impls_on_last_layer('temp/gen_ll1', project_dir)
+
+ def test_generate_all_impls_on_last_layer_on_zip_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
+ self.assert_exists_and_contains_something(project_dir)
+
+ project_zip = os.path.join(ROOT_PATH, "temp/generation_test_project.zip")
+ self.remove_if_exists(project_zip)
+ zip_dir.zip_dir(project_dir, project_zip, [zip_dir.SVN_IGNORE_PATTERN])
+ self.assert_exists_and_contains_something(project_zip)
+
+ self._run_test_generate_all_impls_on_last_layer('temp/gen_ll2', project_zip)
+
+ def _run_test_generate_all_impls_on_last_layer(self, workdir, project):
+ # Create a temp workdir and go there to run the test
+ orig_workdir = os.getcwd()
+ workdir = self._prepare_workdir(workdir)
+ os.chdir(workdir)
+
+ try:
+ cmd = '%s -p "%s" --output output --layer -1 --add-setting-file imaker_variantdir.cfg' % (get_cmd(), project)
+ self.run_command(cmd)
+
+ EXPECTED_DIR = os.path.join(ROOT_PATH, "testdata/generate/expected")
+ self.assert_dir_contents_equal('output', EXPECTED_DIR, ['.svn'])
+ finally:
+ os.chdir(orig_workdir)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/common/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, re, unittest
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+if __name__ == "__main__":
+ # Collect a list of plug-in source paths and plug-in module names
+ paths_and_modnames = plugin_utils.find_plugin_sources(ROOT_PATH)
+ # Create a test suite from them
+ suite = plugin_utils.collect_suite_from_source_list(paths_and_modnames)
+ # Run the suite
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_impl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_impl.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+ExampleML implementation, for use as a template when creating new plug-ins.
+
+The example implementation language simply writes text data into output files
+using the specified encoding. The text data may contain ConfML setting references
+of the form ${SomeFeature.SomeSetting}.
+"""
+
+import os
+import sys
+import logging
+
+from cone.public import plugin
+
+class ExamplemlImpl(plugin.ImplBase):
+ IMPL_TYPE_ID = 'exampleml'
+
+ def __init__(self, resource_ref, configuration, output_objects):
+ plugin.ImplBase.__init__(self, resource_ref, configuration)
+ self.logger = logging.getLogger('cone.exampleml(%s)' % resource_ref)
+ self.output_objects = output_objects
+
+ def generate(self, context=None):
+ for output in self.output_objects:
+ self.logger.debug("Generating '%s'" % output.get_output_file(self.output, self.configuration))
+ output.write_to_file(self.output, self.configuration)
+
+ def list_output_files(self):
+ files = []
+ for output in self.output_objects:
+ files.append(output.get_output_file(self.output, self.configuration))
+ return files
+
+ def get_refs(self):
+ refs = []
+ for output in self.output_objects:
+ refs.extend(output.get_refs())
+ return refs
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_model.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_model.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,83 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+import logging
+
+from cone.public import utils
+
+class Output(object):
+ """
+ Class representing an ExampleML output element.
+ """
+
+ def __init__(self, file, encoding, text):
+ self.file = file
+ self.encoding = encoding
+ self.text = text
+
+ def get_refs(self):
+ """
+ Return a list of all ConfML refs used in this output object.
+ """
+ return utils.extract_delimited_tokens(self.text)
+
+ def get_output_file(self, output_dir, config):
+ """
+ Return the path of the output file specified by this output object.
+ """
+ # Expand ConfML references
+ file = utils.expand_refs_by_default_view(self.file, config.get_default_view())
+ return os.path.normpath(os.path.join(output_dir, file))
+
+ def write_to_file(self, output_dir, config):
+ """
+ Write the text file specified by this output object to the
+ given output directory.
+ """
+ # Get the actual output path and encoding
+ file_path = self.get_output_file(output_dir, config)
+ encoding = utils.expand_refs_by_default_view(self.encoding, config.get_default_view())
+
+ # Generate the binary data to write
+ text = utils.expand_refs_by_default_view(self.text, config.get_default_view())
+ data = text.encode(encoding)
+
+ # Make sure that the output directory exists
+ dir = os.path.dirname(file_path)
+ if dir != '' and not os.path.exists(dir):
+ os.makedirs(dir)
+
+ # Write the file.
+ f = open(file_path, "wb")
+ try: f.write(data)
+ finally: f.close()
+
+ def __eq__(self, other):
+ if type(self) is type(other):
+ for varname in ('file', 'encoding', 'text'):
+ if getattr(self, varname) != getattr(other, varname):
+ return False
+ return True
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ return "Output(file=%r, encoding=%r, text=%r)" % (self.file, self.encoding, self.text)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from cone.public import exceptions, plugin
+import exampleml_impl
+import exampleml_model
+
+class ExamplemlReader(plugin.ReaderBase):
+ NAMESPACE = 'http://www.example.org/xml/exampleml/1'
+ FILE_EXTENSIONS = ['exampleml']
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = ExamplemlReader()
+ outputs = reader._read_outputs(etree)
+ return exampleml_impl.ExamplemlImpl(resource_ref, configuration, outputs)
+
+ def _read_outputs(self, elem):
+ """
+ Read output objects from the given XML element.
+ """
+ result = []
+ for subelem in elem.findall("{%s}output" % self.NAMESPACE):
+ result.append(self._read_output_elem(subelem))
+ return result
+
+ def _read_output_elem(self, elem):
+ """
+ Read an element into an Output object.
+ """
+ file = elem.get('file')
+ if file is None:
+ raise exceptions.ParseError("Element does not have the mandatory 'file' attribute")
+ return exampleml_model.Output(file = file,
+ encoding = elem.get('encoding', 'UTF-8'),
+ text = elem.text or '')
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Multitest impl 1 output 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_2.txt
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_2.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_1.txt
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_1.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_2.txt
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_2.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir/out1.txt
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir/out1.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir2/out2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir2/out2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Test 1 output 2 €
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Value from ConfML: ελληνικά (unicode test), <&> (special char test)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ελληνικά (unicode test), <&> (special char test)
+
+ some/dir/out1.txt
+ UTF-16-LE
+
+ some/dir2
+ out2.txt
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/multitest.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/multitest.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Multitest impl 1 output 1
+ Multitest impl 1 output 2
+
+
+
+
+ Unicode test: ελληνικά
+ Special char test: <&>
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/test.exampleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/test.exampleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+ Value from ConfML: ${TestFeature.Value1}
+ Test test
+ Test 1 output 2 €
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/root.confml
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import exceptions, plugin, api, container
+
+from examplemlplugin import exampleml_reader
+
+def abspath(path):
+ return os.path.normpath(os.path.join(ROOT_PATH, path))
+
+class TestExamplemlGeneration(BaseTestCase):
+
+ def test_generate_from_project(self):
+ project_dir = abspath('project')
+ config = 'root.confml'
+ output_dir = abspath('temp/output')
+ expected_dir = abspath('gen_expected')
+
+ self.remove_if_exists(output_dir)
+
+ prj = api.Project(api.Storage.open(project_dir))
+ config = prj.get_configuration(config)
+ impls = plugin.get_impl_set(config)
+ impls.output = output_dir
+ impls.generate()
+
+ self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'])
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_impl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_impl.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from cone.public import plugin, api
+from examplemlplugin.exampleml_reader import ExamplemlReader
+from examplemlplugin.exampleml_model import Output
+
+class TestExamplemlImpl(unittest.TestCase):
+
+ def setUp(self):
+ project_dir = os.path.join(ROOT_PATH, 'project')
+ self.project = api.Project(api.Storage.open(project_dir))
+ self.config = self.project.get_configuration('root.confml')
+
+ def get_impl(self, ref, index):
+ impl_list = plugin.ImplFactory.get_impls_from_file(ref, self.config)
+ return impl_list[index]
+
+ def test_has_ref(self):
+ impl = self.get_impl('Layer/implml/test.exampleml', 0)
+ self.assertTrue(impl.has_ref(['TestFeature.Value1']))
+ self.assertFalse(impl.has_ref(['TestFeature.Foo']))
+ self.assertFalse(impl.has_ref(['Foo.Bar']))
+
+ def test_list_output_files(self):
+ def oj( p2): # oj = output_join
+ return os.path.normpath(os.path.join('output', p2))
+
+ impl = self.get_impl('Layer/implml/test.exampleml', 0)
+ self.assertEquals(impl.list_output_files(), [oj('test.txt'),
+ oj('some/dir/out1.txt'),
+ oj('some/dir2/out2.txt')])
+
+ impl = self.get_impl('Layer/implml/multitest.implml', 0)
+ self.assertEquals(impl[0].list_output_files(), [oj('multitest1_1.txt'),
+ oj('multitest1_2.txt')])
+
+ impl = self.get_impl('Layer/implml/multitest.implml', 0)
+ self.assertEquals(impl[1].list_output_files(), [oj('multitest2_1.txt'),
+ oj('multitest2_2.txt')])
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+from cone.public import exceptions, plugin, api
+
+from examplemlplugin.exampleml_reader import ExamplemlReader
+from examplemlplugin.exampleml_model import Output
+
+class TestExamplemlReader(unittest.TestCase):
+
+ NAMESPACE = ExamplemlReader.NAMESPACE
+
+ def setUp(self):
+ self.reader = ExamplemlReader()
+
+ def assert_read_output_equals(self, data, expected):
+ etree = ElementTree.fromstring(data)
+ output = self.reader._read_output_elem(etree)
+ self.assertEquals(expected, output)
+
+ def test_read_output(self):
+ data = """Test """
+ self.assert_read_output_equals(data, Output('test1.txt', 'UTF-16', 'Test'))
+
+ data = """Test """
+ self.assert_read_output_equals(data, Output('test2.txt', 'UTF-8', 'Test'))
+
+ data = """ """
+ self.assert_read_output_equals(data, Output('test3.txt', 'UTF-8', ''))
+
+ data = """ """
+ self.assertRaises(exceptions.ParseError, self.reader._read_output_elem, ElementTree.fromstring(data))
+
+ def test_read_outputs(self):
+ data = """
+
+ Test 1
+ Test 2
+
+ """ % self.NAMESPACE
+ outputs = self.reader._read_outputs(ElementTree.fromstring(data))
+ self.assertEquals(outputs,
+ [Output('test1.txt', 'UTF-16-LE', 'Test 1'),
+ Output('test2.txt', 'UTF-8', 'Test 2'),
+ Output('test3.txt', 'UTF-8', '')])
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/ConeExamplePlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from examplemlplugin import __version__
+
+setup(
+ name = "coneexamplemlplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "examplemlplugin.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "",
+ author_email = "authors.email@example.com",
+ description = "Configuration Engine ExampleML plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True,
+
+ # Entry point info.
+ # Plug-ins can register ImplML reader classes by adding entry points
+ # pointing to reader classes under 'cone.plugins.implmlreaders'
+ entry_points = {
+ 'cone.plugins.implmlreaders': [
+ 'exampleml = examplemlplugin.exampleml_reader:ExamplemlReader',
+ # More readers (e.g. different versions of the same ImplML)
+ # could also be registered:
+ #'exampleml_v2 = examplemlplugin.exampleml_reader:ExamplemlReader2',
+ ]
+ }
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/dep-eggs/readme.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/dep-eggs/readme.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+This directory contains all library dependencies needed by any of the plug-ins as egg files.
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../..'))
+assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
+
+# Import plugin_utils from the plug-in sources root
+if PLUGIN_SOURCE_ROOT not in sys.path: sys.path.append(PLUGIN_SOURCE_ROOT)
+import plugin_utils
+
+# Run integration test initialization
+plugin_utils.integration_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/export_standalone.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/export_standalone.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+from testautomation.copy_dir import copy_dir
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+def export_standalone(target_path):
+ """
+ Export any needed extra data for standalone tests.
+ @param target_path: The path where the standalone tests are being exported.
+ """
+ # For example, one could copy test data from a plug-in into the target directory:
+ #dirs_to_copy = ['test_project_', 'test_project_2']
+ #for dir in dirs_to_copy:
+ # copy_dir(source_dir = os.path.join(ROOT_PATH, '../ConeExamplePlugin/examplemlplugin/tests', dir),
+ # target_dir = os.path.join(target_path, 'testdata/generate/test_projects', dir),
+ # dir_ignore_functions = [lambda d: d == '.svn'])
+ pass
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest1_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest1_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Multitest impl 1 output 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest1_2.txt
Binary file configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest1_2.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest2_1.txt
Binary file configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest2_1.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest2_2.txt
Binary file configurationengine/source/plugins/example/integration-test/testdata/generate/expected/multitest2_2.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/expected/some/dir/out1.txt
Binary file configurationengine/source/plugins/example/integration-test/testdata/generate/expected/some/dir/out1.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/expected/some/dir2/out2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/expected/some/dir2/out2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Test 1 output 2 €
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/expected/test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/expected/test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Value from ConfML: ελληνικά (unicode test), <&> (special char test)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ελληνικά (unicode test), <&> (special char test)
+
+ some/dir/out1.txt
+ UTF-16-LE
+
+ some/dir2
+ out2.txt
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/implml/multitest.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/implml/multitest.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Multitest impl 1 output 1
+ Multitest impl 1 output 2
+
+
+
+
+ Unicode test: ελληνικά
+ Special char test: <&>
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/implml/test.exampleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/implml/test.exampleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+ Value from ConfML: ${TestFeature.Value1}
+ Test test
+ Test 1 output 2 €
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/testdata/generate/project/root.confml
Binary file configurationengine/source/plugins/example/integration-test/testdata/generate/project/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/integration-test/unittest_generate.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/integration-test/unittest_generate.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,85 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, shutil, unittest
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation import zip_dir
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+if sys.platform == "win32":
+ CONE_SCRIPT = "cone.cmd"
+else:
+ CONE_SCRIPT = "cone.sh"
+
+def get_cmd(action='generate'):
+ """Return the command used to run the ConE sub-action"""
+ if 'CONE_PATH' in os.environ:
+ CONE_CMD = os.path.join(os.environ['CONE_PATH'], CONE_SCRIPT)
+ if not os.path.exists(CONE_CMD):
+ raise RuntimeError("'%s' does not exist!" % CONE_CMD)
+ return '"%s" %s' % (CONE_CMD, action)
+ else:
+ SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+ assert os.path.split(SOURCE_ROOT)[1] == 'source'
+ cmd = 'python "%s" %s' % (os.path.normpath(os.path.join(SOURCE_ROOT, 'scripts/cone_tool.py')), action)
+ return cmd
+
+class TestExampleGenerate(BaseTestCase):
+
+ def _prepare_workdir(self, workdir):
+ workdir = os.path.join(ROOT_PATH, workdir)
+ self.recreate_dir(workdir)
+
+ # Any needed extra preparation can be done here
+
+ return workdir
+
+ def test_generate_on_file_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
+ self.assert_exists_and_contains_something(project_dir)
+ self._run_test_generate('temp/gen1', project_dir)
+
+ def test_generate_on_zip_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
+ self.assert_exists_and_contains_something(project_dir)
+
+ project_zip = os.path.join(ROOT_PATH, "temp/generation_test_project.zip")
+ self.remove_if_exists(project_zip)
+ zip_dir.zip_dir(project_dir, project_zip, [zip_dir.SVN_IGNORE_PATTERN])
+ self.assert_exists_and_contains_something(project_zip)
+
+ self._run_test_generate('temp/gen2', project_zip)
+
+ def _run_test_generate(self, workdir, project):
+ # Create a temp workdir and go there to run the test
+ orig_workdir = os.getcwd()
+ workdir = self._prepare_workdir(workdir)
+ os.chdir(workdir)
+
+ try:
+ cmd = '%s -p "%s" --output output --add-setting-file imaker_variantdir.cfg' % (get_cmd(), project)
+ self.run_command(cmd)
+
+ EXPECTED_DIR = os.path.join(ROOT_PATH, "testdata/generate/expected")
+ self.assert_dir_contents_equal('output', EXPECTED_DIR, ['.svn'])
+ finally:
+ os.chdir(orig_workdir)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/example/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, re, unittest
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+if __name__ == "__main__":
+ # Collect a list of plug-in source paths and plug-in module names
+ paths_and_modnames = plugin_utils.find_plugin_sources(ROOT_PATH)
+ # Create a test suite from them
+ suite = plugin_utils.collect_suite_from_source_list(paths_and_modnames)
+ # Run the suite
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/nose_unittests.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/nose_unittests.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+[nosetests]
+verbosity=3
+include=unittest
+with-xunit=1
+xunit-file=cone-unittests.xml
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/plugin_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/plugin_utils.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,317 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest, re
+import build_egg_info
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Path to the source/ directory
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
+assert os.path.split(SOURCE_ROOT)[1] == 'source'
+
+# Path to the source/plugins directory
+PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(SOURCE_ROOT, 'plugins'))
+assert os.path.isdir(PLUGIN_SOURCE_ROOT)
+
+def plugin_test_init(root_path, plugin_source_relative_path='../..'):
+ """
+ Initialize things so that plug-in unit tests can be run.
+
+ @param root_path: Path of the __init__.py file calling this function.
+ @param plugin_source_relative_path: Path to the plug-in's source root relative
+ to root_path. Usually this should be '../..', since this function is intended
+ to be called from a plug-in's tests/__init__.py file.
+
+ """
+ # Add paths so that the unit tests work
+ # -------------------------------------
+ extra_paths = [
+ # For module 'cone'
+ SOURCE_ROOT,
+
+ # For module 'testautomation'
+ os.path.join(SOURCE_ROOT, 'testautomation'),
+
+ # For the plug-in module.
+ # Since the method is expected to be called from e.g.
+ # source/plugins/ConeSomePlugin/someplugin/tests/__init__.py, this will then be
+ # source/plugins/ConeSomePlugin, in which case the module 'someplugin' can be
+ # imported
+ os.path.join(root_path, plugin_source_relative_path)
+ ]
+ for p in extra_paths:
+ p = os.path.normpath(p)
+ if p not in sys.path: sys.path.append(p)
+
+ # Generate egg-info for the plug-in.
+ # The egg-info needs to be up-to-date, or the plug-in framework will not be able
+ # to find the plug-in's ImplML reader classes
+ plugin_path = os.path.normpath(os.path.join(root_path, plugin_source_relative_path))
+ assert 'setup.py' in os.listdir(plugin_path), "Path '%s' does not contain 'setup.py" % plugin_path
+ build_egg_info.generate_egg_info(plugin_path)
+
+def integration_test_init(root_path):
+ """
+ Initialize things so that integration tests can be run.
+
+ This function is intended to be called from a sub-package's integration-test/__init__.py file.
+ @param root_path: Path of the __init__.py file calling this function.
+ """
+ # Add paths so that the unit tests work
+ # -------------------------------------
+ extra_paths = [
+ # For module 'cone' (may be needed in some tests for e.g. asserts)
+ SOURCE_ROOT,
+
+ # For module 'testautomation'
+ os.path.join(SOURCE_ROOT, 'testautomation'),
+ ]
+ for p in extra_paths:
+ p = os.path.normpath(p)
+ if p not in sys.path: sys.path.append(p)
+
+ # Collect plug-in source paths (common + current)
+ temp = []
+ temp += [path for path, _ in find_plugin_sources(os.path.join(PLUGIN_SOURCE_ROOT, 'common'))]
+ temp += [path for path, _ in find_plugin_sources(os.path.normpath(os.path.join(root_path, '..')))]
+ plugin_paths = []
+ for p in temp:
+ if p not in plugin_paths: plugin_paths.append(p)
+
+ # Add things to PYTHONPATH so that running cone_tool.py works
+ paths = []
+ paths.append(SOURCE_ROOT) # For module 'cone'
+ paths.extend(plugin_paths)
+ os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + ';'.join(paths)
+
+ # Generate egg-info for the plug-ins.
+ # The egg-info needs to be up-to-date, or the plug-in framework will not be able
+ # to find the plug-in's ImplML reader classes
+ for p in plugin_paths:
+ assert 'setup.py' in os.listdir(p), "Path '%s' does not contain 'setup.py" % p
+ build_egg_info.generate_egg_info(p)
+
+def init_all():
+ """
+ Add all plug-ins to sys.path and PYTHONPATH so that running all
+ plug-in unit tests and integration tests work.
+ """
+ # Find all plug-in source directories
+ plugin_paths = []
+ temp = find_all_plugin_sources(os.path.join(PLUGIN_SOURCE_ROOT))
+ for package_name, sources in temp.iteritems():
+ for path, modname in sources:
+ plugin_paths.append(path)
+
+ # Add paths so that the unit tests work
+ # -------------------------------------
+ extra_paths = [
+ # For module 'cone' (may be needed in some tests for e.g. asserts)
+ SOURCE_ROOT,
+
+ # For module 'testautomation'
+ os.path.join(SOURCE_ROOT, 'testautomation'),
+ ] + plugin_paths
+ for p in extra_paths:
+ p = os.path.normpath(p)
+ if p not in sys.path: sys.path.append(p)
+
+ # Add things to PYTHONPATH so that running cone_tool.py works
+ paths = []
+ paths.append(SOURCE_ROOT) # For module 'cone'
+ paths.extend(plugin_paths)
+ os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + ';'.join(paths)
+
+ # Generate egg-info for the plug-ins.
+ # The egg-info needs to be up-to-date, or the plug-in framework will not be able
+ # to find the plug-in's ImplML reader classes
+ for p in plugin_paths:
+ assert 'setup.py' in os.listdir(p), "Path '%s' does not contain 'setup.py" % p
+ build_egg_info.generate_egg_info(p)
+
+def collect_test_suite_from_dir(root_path):
+ """
+ Return a test suite containing all tests in 'unittest_*.py' files under the given directory.
+ """
+ # Find all unittest_*.py files in the folder
+ test_modules = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(root_path))
+ # Strip .py endings
+ test_modules = map(lambda name: name[:-3], test_modules)
+
+ # Add the root path as the first one in sys.path, so that
+ # __import__() checks that first when attempting to import a module
+ sys.path.insert(0, root_path)
+
+ try:
+ suite = unittest.TestSuite()
+ for test_module in test_modules:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+ finally:
+ # Remove root_path from sys.path
+ del sys.path[0]
+
+def collect_suite_from_source_list(paths_and_modnames):
+ suite = unittest.TestSuite()
+
+ # Add the source paths to sys.path
+ for path, modname in paths_and_modnames:
+ if path not in sys.path:
+ sys.path.append(path)
+
+ # Import the tests in a separate loop, because otherwise the ImplML reader classes
+ # could be loaded before all plug-ins are in sys.path
+ for path, modname in paths_and_modnames:
+ try:
+ m = __import__(modname + '.tests')
+ suite.addTests(m.tests.collect_suite())
+ except ImportError:
+ print "Tests for '%s' not added, no 'tests' module found" % path
+
+ return suite
+
+def get_plugin_module_name(plugin_src_path):
+ """
+ Return the name of the plug-in's module under given plug-in source path.
+
+ >>> get_tests_module('source/plugins/common/ConeContentPlugin')
+ 'contentplugin'
+ >>> get_tests_module('foo')
+ None
+ """
+ if not os.path.isdir(plugin_src_path):
+ return None
+
+ for name in os.listdir(plugin_src_path):
+ path = os.path.join(plugin_src_path, name)
+ if os.path.isdir(path) and '__init__.py' in os.listdir(path):
+ return name
+ return None
+
+def find_plugin_sources(subpackage_root_path):
+ """
+ Return ConE plug-in source directories from the given path.
+
+ All sub-directories in subpackage_root_path of the form Cone*Plugin/ containing
+ a sub-directory that is a python module are returned.
+
+ @param path: The directory from where to find the entries.
+ @return: A list of tuples, each containing (, ).
+ """
+ pattern = re.compile(r'^Cone.*Plugin$')
+
+ # Collect a list of plug-in source paths and plug-in module names
+ result = []
+ for name in os.listdir(subpackage_root_path):
+ path = os.path.join(subpackage_root_path, name)
+ if pattern.match(name) is not None:
+ modname = get_plugin_module_name(path)
+ if modname is not None:
+ result.append((path, modname))
+ return result
+
+def find_all_plugin_sources(plugins_root_path):
+ """
+ Return all ConE plug-in source directories from the plugins/ root
+ directory.
+ @return: A dictionary containing the output of find_plugin_sources() by
+ plug-in sub-packages.
+ >>> find_all_plugin_sources('C:/work/cone-trunk/source/plugins')
+ {'common': [('C:/work/cone-trunk/source/plugins/common/ConeContentPlugin', 'contentplugin'),
+ ('C:/work/cone-trunk/source/plugins/common/ConeTemplatePlugin', 'templatemlplugin')],
+ 'example': [('C:/work/cone-trunk/source/plugins/example/ConeExamplePlugin', 'examplemlplugin')]}
+ """
+ result = {}
+ for name in os.listdir(plugins_root_path):
+ path = os.path.join(plugins_root_path, name)
+ if os.path.isdir(path):
+ sources = find_plugin_sources(path)
+ if sources: result[name] = sources
+ return result
+
+def find_plugin_package_subpaths(subpath, package_name=None):
+ """
+ Return a list of plug-in package sub-paths based on the given plug-in package name.
+
+ The returned list always contains the sub-path for common plug-ins, and
+ additionally for an extra plug-in package based on the given package name.
+
+ This function can be used to find specifically named files or directories
+ under the plug-in paths. E.g. find all 'integration-test' directories:
+
+ >>> find_plugin_package_subpaths('integration-test', 'symbian')
+ [('common', 'C:\\cone\\trunk\\sources\\plugins\\common\\integration-test'),
+ ('symbian', 'C:\\cone\\trunk\\sources\\plugins\\symbian\\integration-test')]
+
+ @param package_name: Name of the extra plug-in package. Can be None, '',
+ 'common' or an existing plug-in package.
+ @return: List of tuples (package_name, subpath).
+
+ @raise ValueError: The given package_name was invalid.
+ """
+ result = []
+
+ def add(package_name):
+ package_dir = os.path.join(PLUGIN_SOURCE_ROOT, package_name)
+
+ if not os.path.exists(package_dir):
+ raise ValueError("Invalid plug-in package name: '%s'" % package_name)
+
+ path = os.path.normpath(os.path.join(package_dir, subpath))
+ if os.path.exists(path):
+ result.append((package_name, path))
+
+ add('common')
+ if package_name not in (None, '', 'common'):
+ add(package_name)
+
+ return result
+
+
+def find_plugin_sources_by_package(package_name=None):
+ """
+ Return a list of plug-in source paths based on the given plug-in package name.
+
+ The returned list always contains sources of common plug-ins, and
+ additionally extra plug-in sources based on the given package name.
+
+ @param package_name: Name of the extra plug-in package. Can be None, '',
+ 'common' or an existing plug-in package.
+ @raise ValueError: The given package_name was invalid.
+ """
+ result = []
+
+ # Find all plug-in sources
+ sources = find_all_plugin_sources(PLUGIN_SOURCE_ROOT)
+
+ # Always return common plug-ins
+ if 'common' in sources:
+ for path, modname in sources['common']:
+ result.append(path)
+
+ # Return extra plug-ins if necessary
+ if package_name not in (None, '', 'common'):
+ if package_name not in sources:
+ raise ValueError("Invalid plug-in package name: '%s'" % package_name)
+ else:
+ for path, modname in sources[package_name]:
+ result.append(path)
+
+ return result
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/readme.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/readme.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+This directory contains ConE plug-in packages.
+
+Each package is a sub-directory here, and plugin_utils.py contains utility
+functions for dealing with e.g. running plug-in tests.
+
+For more information see the ConE documentation.
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, re, unittest
+import plugin_utils
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+if __name__ == "__main__":
+ # Collect a list of plug-in source paths and plug-in module names
+ sources = plugin_utils.find_all_plugin_sources(ROOT_PATH)
+
+ # Flatten the source list
+ flattened_sources = []
+ for subpackage_name, paths_and_modnames in sources.iteritems():
+ flattened_sources.extend(paths_and_modnames)
+
+ # Create a test suite from them
+ suite = plugin_utils.collect_suite_from_source_list(flattened_sources)
+
+ # Run the suite
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
+
+
+import pkg_resources
+import sys,os
+
+try:
+ pkg_resources.require("Cone")
+except pkg_resources.DistributionNotFound:
+ ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+ sys.path.append(ROOT_PATH)
+ sys.path.append(os.path.join(ROOT_PATH,'..'))
+ sys.path.append(os.path.join(ROOT_PATH,'../..'))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_comparator.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_comparator.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,324 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import logging
+from cone.public import plugin
+from crml_model import *
+
+class CrmlComparator(object):
+ def __init__(self, resource_ref, repo):
+ self.logger = logging.getLogger('cone.crml.comparator(%s)' % resource_ref)
+ self.resource_ref = resource_ref
+ self.repo = repo
+
+ @classmethod
+ def get_flat_comparison_id(cls, repo):
+ """
+ Return the flat comparison ID for the given repository.
+ """
+ return cls._num_to_str(repo.uid_value)
+
+ @classmethod
+ def get_flat_comparison_extra_data(cls, repo):
+ return {'repo': repo}
+
+ @classmethod
+ def _num_to_str(cls, number):
+ if isinstance(number, basestring):
+ try:
+ number = long(number, 10)
+ except ValueError:
+ number = long(number, 16)
+ return "0x%08X" % number
+
+ def flat_compare(self, target_resource_ref, target_repo):
+ """
+ Compare two CRML repository models.
+ @return: A plugin.FlatComparisonResult object.
+ """
+ source_repo = self.repo
+
+ result = plugin.FlatComparisonResult()
+
+ source_repo_uid = self._num_to_str(source_repo.uid_value)
+ target_repo_uid = self._num_to_str(target_repo.uid_value)
+
+ if source_repo_uid != target_repo_uid:
+ raise RuntimeError("Comparing CRML implementations instances that don't have the same repository UID (%r vs. %r)" % (source_repo_uid, target_repo_uid))
+
+ # Default field contents for new entries
+ default_field_content = {
+ 'data' : {}}
+
+ Entry = plugin.FlatComparisonResultEntry
+
+ if self.resource_ref != target_resource_ref:
+ result.modified.append(Entry(value_id = 'file',
+ source_value = self.resource_ref,
+ target_value = target_resource_ref,
+ data = {'source_repo': source_repo,
+ 'target_repo': target_repo}))
+
+ # Compare repository attributes
+ # -----------------------------
+ repo_mods = self._flat_compare_object_attrs(
+ key_id = None,
+ source_obj = source_repo,
+ target_obj = target_repo,
+ varnames = ('uid_name', 'owner', 'backup', 'rfs', 'access'))
+ content = default_field_content.copy()
+ content['data'] = {'source_repo': source_repo,
+ 'target_repo': target_repo}
+ self._fill_in_entry_fields(repo_mods, content)
+ result.modified.extend(repo_mods)
+
+ source_data = self._get_flat_comparison_data(source_repo)
+ target_data = self._get_flat_comparison_data(target_repo)
+
+ # Find entries only in source
+ # ---------------------------
+ for id, crml_key in source_data.iteritems():
+ if id not in target_data:
+ data = {'repo': source_repo,
+ 'key': crml_key}
+ result.only_in_source.append(Entry(sub_id=id, data=data))
+
+ # Find entries only in target
+ # ---------------------------
+ for id, crml_key in target_data.iteritems():
+ if id not in source_data:
+ data = {'repo': source_repo,
+ 'key': crml_key}
+ result.only_in_target.append(Entry(sub_id=id, data=data))
+
+ # Find differing entries
+ # ----------------------
+ for id, source_key in source_data.iteritems():
+ if id not in target_data: continue
+ target_key = target_data[id]
+ if source_key == target_key: continue
+
+ # Get the comparison result for the key
+ comp_result = self._get_flat_key_comparison_result(id, source_key, target_key)
+
+ # Fill in the missing fields of the result entries
+ content = default_field_content.copy()
+ content['data'] = {'repo' : source_repo,
+ 'key' : source_key}
+ self._fill_in_entry_fields(comp_result.only_in_source, content)
+
+ content = default_field_content.copy()
+ content['data'] = {'repo' : target_repo,
+ 'key' : target_key}
+ self._fill_in_entry_fields(comp_result.only_in_target, content)
+
+ content = default_field_content.copy()
+ content['data'] = {'source_repo' : source_repo,
+ 'target_repo' : target_repo,
+ 'source_key' : source_key,
+ 'target_key' : target_key}
+ self._fill_in_entry_fields(comp_result.modified, content)
+
+ result.extend(comp_result)
+
+ return result
+
+ def _fill_in_entry_fields(self, entry_list, field_contents):
+ for entry in entry_list:
+ for varname, value in field_contents.iteritems():
+ if getattr(entry, varname) is None:
+ setattr(entry, varname, value)
+
+ def _get_flat_comparison_data(self, repository):
+ """
+ Return a dictionary containing all keys in the repository.
+
+ The dictionary will have the CRML key UIDs as the dictionary keys and
+ the CRML key objects as the values.
+ """
+ data = {}
+ for key in repository.keys:
+ if isinstance(key, (CrmlSimpleKey, CrmlBitmaskKey)):
+ id = self._num_to_str(key.int)
+ elif isinstance(key, CrmlKeyRange):
+ id = self._num_to_str(key.first_int) + '-' + self._num_to_str(key.last_int)
+ data[id] = key
+ return data
+
+ def _get_flat_key_comparison_result(self, key_id, source_key, target_key):
+ """
+ Return a flat comparison result for a source and target CRML key pair.
+
+ @param key_id: The ID of the key, e.g. '0x00000001' for a simple key or
+ '0x00001000-0x00001FFF' for a key range.
+ @param source_key: The source key object.
+ @param target_key: The target key object.
+ @return: A plugin.FlatComparisonResult object.
+ """
+ result = plugin.FlatComparisonResult()
+
+ if type(source_key) == type(target_key):
+ comp_funcs = {CrmlSimpleKey: self._flat_compare_simple_keys,
+ CrmlBitmaskKey: self._flat_compare_bitmask_keys,
+ CrmlKeyRange: self._flat_compare_key_ranges}
+ func = comp_funcs[type(source_key)]
+ result.extend(func(key_id, source_key, target_key))
+ else:
+ # Perform base key comparison
+ result.modified.extend(self._flat_compare_base_keys(key_id, source_key, target_key))
+
+ # Add an entry for key type change
+ type_ids = {CrmlSimpleKey: 'simple_key',
+ CrmlBitmaskKey: 'bitmask_key',
+ CrmlKeyRange: 'key_range'}
+ entry = plugin.FlatComparisonResultEntry(
+ sub_id = key_id,
+ value_id = 'key_type',
+ source_value = type_ids[type(source_key)],
+ target_value = type_ids[type(target_key)])
+ result.modified.append(entry)
+
+ return result
+
+ def _flat_compare_object_attrs(self, key_id, source_obj, target_obj, varnames):
+ result = []
+ for varname in varnames:
+ sval = getattr(source_obj, varname)
+ tval = getattr(target_obj, varname)
+
+ if sval != tval:
+ if isinstance(sval, CrmlAccess):
+ result.extend(self._flat_compare_object_attrs(
+ key_id, sval, tval,
+ ('cap_rd', 'cap_wr', 'sid_rd', 'sid_wr')))
+ else:
+ entry = plugin.FlatComparisonResultEntry(
+ sub_id = key_id,
+ value_id = varname,
+ source_value = sval,
+ target_value = tval)
+ result.append(entry)
+ return result
+
+ def _flat_compare_base_keys(self, key_id, source_key, target_key, extra_varnames=[]):
+ varnames = ['name', 'backup', 'read_only', 'access']
+ varnames.extend(extra_varnames)
+ return self._flat_compare_object_attrs(key_id, source_key, target_key, varnames)
+
+ def _flat_compare_simple_keys(self, key_id, source_key, target_key):
+ mod = self._flat_compare_base_keys(key_id, source_key, target_key,
+ extra_varnames=['ref', 'type'])
+ return plugin.FlatComparisonResult(modified=mod)
+
+ def _flat_compare_bitmask_keys(self, key_id, source_key, target_key):
+ mod = self._flat_compare_base_keys(key_id, source_key, target_key,
+ extra_varnames=['type'])
+ only_in_source = []
+ only_in_target = []
+
+ def get_bits_dict(key):
+ bits = {}
+ for bit in key.bits:
+ bits[bit.index] = bit
+ return bits
+
+ src_bits = get_bits_dict(source_key)
+ tgt_bits = get_bits_dict(target_key)
+
+ # Find bits only in source
+ # ------------------------
+ for index in src_bits.iterkeys():
+ if index not in tgt_bits:
+ entry = plugin.FlatComparisonResultEntry(
+ sub_id = "%s (bit %s)" % (key_id, index))
+ only_in_source.append(entry)
+
+ # Find bits only in target
+ # ------------------------
+ for index in tgt_bits.iterkeys():
+ if index not in src_bits:
+ entry = plugin.FlatComparisonResultEntry(
+ sub_id = "%s (bit %s)" % (key_id, index))
+ only_in_target.append(entry)
+
+ # Find modified bits
+ # ------------------
+ for index, src_bit in src_bits.iteritems():
+ if index not in tgt_bits: continue
+ tgt_bit = tgt_bits[index]
+
+ mod.extend(self._flat_compare_object_attrs(
+ key_id = "%s (bit %s)" % (key_id, index),
+ source_obj = src_bit,
+ target_obj = tgt_bit,
+ varnames = ('ref', 'invert')))
+
+ return plugin.FlatComparisonResult(modified = mod,
+ only_in_source = only_in_source,
+ only_in_target = only_in_target)
+
+ def _flat_compare_key_ranges(self, key_id, source_key, target_key):
+ mod = self._flat_compare_base_keys(key_id, source_key, target_key,
+ extra_varnames=['ref', 'index_bits', 'first_index'])
+ only_in_source = []
+ only_in_target = []
+
+ # Use hexadecimal format for index bits
+ for entry in mod:
+ if entry.value_id == 'index_bits':
+ entry.source_value = self._num_to_str(entry.source_value)
+ entry.target_value = self._num_to_str(entry.target_value)
+
+ def get_subkeys_dict(key):
+ subkeys = {}
+ for sk in key.subkeys:
+ subkeys[sk.int] = sk
+ return subkeys
+
+ src_subkeys = get_subkeys_dict(source_key)
+ tgt_subkeys = get_subkeys_dict(target_key)
+
+ # Find sub-keys only in source
+ # ----------------------------
+ for uid in src_subkeys.iterkeys():
+ if uid not in tgt_subkeys:
+ entry = plugin.FlatComparisonResultEntry(
+ sub_id = "%s (sub-key %s)" % (key_id, self._num_to_str(uid)))
+ only_in_source.append(entry)
+
+ # Find sub-keys only in target
+ # ----------------------------
+ for uid in tgt_subkeys.iterkeys():
+ if uid not in src_subkeys:
+ entry = plugin.FlatComparisonResultEntry(
+ sub_id = "%s (sub-key %s)" % (key_id, self._num_to_str(uid)))
+ only_in_target.append(entry)
+
+ # Find modified bits
+ # ------------------
+ for uid, src_subkey in src_subkeys.iteritems():
+ if uid not in tgt_subkeys: continue
+ tgt_subkey = tgt_subkeys[uid]
+
+ mod.extend(self._flat_compare_object_attrs(
+ key_id = "%s (sub-key %s)" % (key_id, self._num_to_str(uid)),
+ source_obj = src_subkey,
+ target_obj = tgt_subkey,
+ varnames = ('ref', 'type', 'name')))
+
+ return plugin.FlatComparisonResult(modified = mod,
+ only_in_source = only_in_source,
+ only_in_target = only_in_target)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_impl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_impl.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,148 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+import logging
+
+from cone.public import exceptions, plugin, utils, api
+import crml_writer, crml_comparator
+from crml_model import *
+
+class CrmlImpl(plugin.ImplBase):
+ IMPL_TYPE_ID = 'crml'
+
+ RFS_RECORDS_LIST_VARNAME = 'crml_cenrep_rfs_records_list'
+ RFS_TXT_GENERATED_VARNAME = 'crml_cenrep_rfs_txt_generated'
+
+ def __init__(self, resource_ref, configuration, repository):
+ plugin.ImplBase.__init__(self, resource_ref, configuration)
+ self.resource_ref = resource_ref
+ self.configuration = configuration
+ self.logger = logging.getLogger('cone.crml(%s)' % self.resource_ref)
+ self.repository = repository
+
+ def generate(self, context=None):
+ # Quick fix
+ if context:
+ self.generation_context = context
+ file_path = self._get_cenrep_txt_file_path()
+ self.logger.debug("Generating file '%s'..." % file_path)
+
+ # Generate CenRep text data and write it to the output file
+ writer = crml_writer.CrmlTxtWriter(self.configuration, self.logger)
+ data = writer.get_cenrep_txt_data(self.repository).encode('UTF-16')
+ self._write_to_file(file_path, data)
+
+
+ # Collect the record for cenrep_rfs.txt generation in post_generate()
+ if self.generation_context is not None:
+ rfs_record = writer.get_cenrep_rfs_record(self.repository)
+ if rfs_record:
+ # Add the record to the dictionary
+ data_dict = self.generation_context.impl_data_dict
+ VARNAME = self.RFS_RECORDS_LIST_VARNAME
+ if VARNAME not in data_dict:
+ data_dict[VARNAME] = []
+ data_dict[VARNAME].append(rfs_record)
+
+ def post_generate(self, context=None):
+ # Quick fix
+ if context:
+ self.generation_context = context
+ if self._is_cenrep_rfs_txt_to_be_generated():
+ # Generate CenRep RFS text file if not already generated
+ data_dict = self.generation_context.impl_data_dict
+ if self.RFS_TXT_GENERATED_VARNAME not in data_dict:
+ rfs_records = data_dict.get(self.RFS_RECORDS_LIST_VARNAME, [])
+
+ file_path = self._get_cenrep_rfs_txt_file_path()
+ writer = crml_writer.CrmlTxtWriter(self.configuration, self.logger)
+ data = writer.get_cenrep_rfs_txt_data(rfs_records).encode('UTF-16')
+ self._write_to_file(file_path, data)
+
+ data_dict[self.RFS_TXT_GENERATED_VARNAME] = True
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ files = [self._get_cenrep_txt_file_path()]
+ if self._is_cenrep_rfs_txt_to_be_generated():
+ files.append(self._get_cenrep_rfs_txt_file_path())
+ return files
+
+ def get_refs(self):
+ if self.repository is None:
+ return []
+ else:
+ return self.repository.get_refs()
+
+ def get_flat_comparison_id(self):
+ return crml_comparator.CrmlComparator.get_flat_comparison_id(self.repository)
+
+ def get_flat_comparison_extra_data(self):
+ return crml_comparator.CrmlComparator.get_flat_comparison_extra_data(self.repository)
+
+ @classmethod
+ def get_flat_comparison_impl_type_id(cls):
+ return 'crml'
+
+ def flat_compare(self, other):
+ comparator = crml_comparator.CrmlComparator(self.resource_ref, self.repository)
+ return comparator.flat_compare(other.resource_ref, other.repository)
+
+ def _get_cenrep_txt_file_path(self):
+ """
+ Return the full path to the CenRep text file generated by this implementation
+ """
+ uid = self.repository.uid_value
+ if uid.startswith('0x'): uid = uid[2:]
+ return os.path.normpath(os.path.join(self.output, uid + '.txt'))
+
+ def _get_cenrep_rfs_txt_file_path(self):
+ """
+ Return the full path to the CenRep RFS text file
+ """
+ # cenrep_rfs.txt goes to a different place than the rest of
+ # the CenRep files, so temporarily override plugin_output
+ # for that purpose
+ orig_pluginoutput = self.plugin_output
+ self.plugin_output = 'private/100059C9'
+ rfs_txt_path = os.path.normpath(os.path.join(self.output, 'cenrep_rfs.txt'))
+ self.plugin_output = orig_pluginoutput
+ return rfs_txt_path
+
+ def _is_cenrep_rfs_txt_to_be_generated(self):
+ """
+ Return whether the CenRep RFS text file is to be generated.
+ """
+ if self.generation_context is None:
+ return False
+
+ targets = self.generation_context.tags.get('target', [])
+ return 'core' in targets or 'rofs2' in targets
+
+ def _write_to_file(self, file_path, data):
+ # Create directories for the file if necessary
+ file_dir = os.path.dirname(file_path)
+ if file_dir != '' and not os.path.exists(file_dir):
+ os.makedirs(file_dir)
+
+ # Write data
+ f = open(file_path, "wb")
+ try: f.write(data)
+ finally: f.close()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_model.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_model.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,222 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+class _CrmlObjectBase(object):
+ """
+ Common utility base class for all CRML objects for implementing
+ operations like repr(), copy() etc.
+ """
+
+ # Variable names used in simple object equality comparison
+ SIMPLE_EQ_VARNAMES = []
+
+ def __repr__(self):
+ return "%s(**%r)" % (self.__class__.__name__, vars(self))
+
+ def __get_filtered_dict(self, source_dict, allowed_keys):
+ result = {}
+ for key in allowed_keys:
+ if key in source_dict:
+ result[key] = source_dict[key]
+ return result
+
+ def __eq__(self, other):
+ # 1. Compare type
+ if type(self) is not type(other):
+ return False
+
+ # 2. Compare all members that can be simply compared using ==
+ varnames = self.__class__.SIMPLE_EQ_VARNAMES
+ dict_self = self.__get_filtered_dict(vars(self), varnames)
+ dict_other = self.__get_filtered_dict(vars(other), varnames)
+ if dict_self != dict_other:
+ return False
+
+ # 3. Do any extra comparing
+ if not self._do_extra_eq_handling(other):
+ return False
+
+ return True
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def _do_extra_eq_handling(self, other):
+ """
+ If sub-classes need to do any extra handling in __eq__(), they
+ should implement this method and do it here.
+ @return: True if self is equal to other, False if not.
+ """
+ return True
+
+ def copy(self):
+ """
+ Return a deep copy of this object.
+ """
+ new_obj = self.__class__(**vars(self))
+ self._do_extra_copy_handling(new_obj)
+ return new_obj
+
+ def _do_extra_copy_handling(self, new_object):
+ """
+ If sub-classes need to do any extra handling in copy(), they
+ should implement this method and do it here.
+ @param new_object: The new copied object, a shallow copy at this point.
+ """
+ return
+
+class CrmlAccess(_CrmlObjectBase):
+ SIMPLE_EQ_VARNAMES = ['cap_rd', 'cap_wr', 'sid_rd', 'sid_wr']
+
+ def __init__(self, **kwargs):
+ self.cap_rd = kwargs.get('cap_rd')
+ self.cap_wr = kwargs.get('cap_wr')
+ self.sid_rd = kwargs.get('sid_rd')
+ self.sid_wr = kwargs.get('sid_wr')
+
+
+class CrmlRepository(_CrmlObjectBase):
+ SIMPLE_EQ_VARNAMES = ['uid_value', 'uid_name', 'owner', 'backup', 'rfs', 'access', 'keys', 'version']
+
+ def __init__(self, **kwargs):
+ self.uid_value = kwargs.get('uid_value')
+ self.uid_name = kwargs.get('uid_name')
+ self.owner = kwargs.get('owner')
+ self.backup = kwargs.get('backup', False)
+ self.rfs = kwargs.get('rfs', False)
+ self.access = kwargs.get('access', CrmlAccess())
+ self.keys = kwargs.get('keys', [])
+ self.version = kwargs.get('version', '1')
+
+ def _do_extra_copy_handling(self, new_object):
+ new_keys = []
+ for key in new_object.keys:
+ new_keys.append(key.copy())
+ new_object.keys = new_keys
+
+ self.access = new_object.access.copy()
+
+ def get_refs(self):
+ result = []
+ for key in self.keys:
+ result.extend(key.get_refs())
+ return result
+
+class CrmlKeyBase(object):
+ def __init__(self, **kwargs):
+ self.ref = kwargs.get('ref')
+ self.name = kwargs.get('name')
+ self.backup = kwargs.get('backup', False)
+ self.read_only = kwargs.get('read_only', False)
+ self.access = kwargs.get('access', CrmlAccess())
+
+class CrmlSimpleKey(CrmlKeyBase, _CrmlObjectBase):
+ SIMPLE_EQ_VARNAMES = ['ref', 'name', 'int', 'type', 'backup', 'read_only', 'access']
+
+ def __init__(self, **kwargs):
+ CrmlKeyBase.__init__(self, **kwargs)
+ try:
+ self.ref = kwargs['ref']
+ self.int = kwargs['int']
+ self.type = kwargs.get('type', 'int')
+ except KeyError, e:
+ raise ValueError("Mandatory argument '%s' not given!" % e.message)
+
+ def _do_extra_copy_handling(self, new_object):
+ self.access = new_object.access.copy()
+
+ def get_refs(self):
+ return [self.ref]
+
+class CrmlBitmaskKey(CrmlKeyBase, _CrmlObjectBase):
+ SIMPLE_EQ_VARNAMES = ['int', 'type', 'backup', 'read_only', 'access', 'name', 'bits']
+
+ def __init__(self, **kwargs):
+ CrmlKeyBase.__init__(self, **kwargs)
+ try:
+ self.int = kwargs['int']
+ self.type = kwargs.get('type', 'int')
+ self.bits = kwargs.get('bits', [])
+ except KeyError, e:
+ raise ValueError("Mandatory argument '%s' not given!" % e.message)
+
+ def _do_extra_copy_handling(self, new_object):
+ new_bits = []
+ for bit in new_object.bits:
+ new_bits.append(bit.copy())
+ new_object.bits = new_bits
+
+ self.access = new_object.access.copy()
+
+ def get_refs(self):
+ return [bit.ref for bit in self.bits]
+
+class CrmlBit(_CrmlObjectBase):
+ SIMPLE_EQ_VARNAMES = ['ref', 'index', 'invert']
+
+ def __init__(self, **kwargs):
+ try:
+ self.ref = kwargs['ref']
+ self.index = kwargs['index']
+ self.invert = kwargs.get('invert', False)
+ except KeyError, e:
+ raise ValueError("Mandatory argument '%s' not given!" % e.message)
+
+class CrmlKeyRange(CrmlKeyBase, _CrmlObjectBase):
+ SIMPLE_EQ_VARNAMES = ['ref', 'name', 'first_int', 'last_int', 'first_index', 'index_bits', 'count_int', 'backup', 'read_only', 'access', 'subkeys']
+
+ def __init__(self, **kwargs):
+ CrmlKeyBase.__init__(self, **kwargs)
+ try:
+ self.first_int = kwargs['first_int']
+ self.last_int = kwargs['last_int']
+ self.first_index = kwargs.get('first_index', 0)
+ self.index_bits = kwargs.get('index_bits')
+ self.count_int = kwargs.get('count_int')
+ self.subkeys = kwargs.get('subkeys', [])
+ except KeyError, e:
+ raise ValueError("Mandatory argument '%s' not given!" % e.message)
+
+ def _do_extra_copy_handling(self, new_object):
+ new_subkeys = []
+ for subkey in new_object.subkeys:
+ new_subkeys.append(subkey.copy())
+ new_object.subkeys = new_subkeys
+
+ self.access = new_object.access.copy()
+
+ def get_refs(self):
+ if self.ref is not None:
+ refs = [self.ref]
+ for sk in self.subkeys:
+ refs.append(self.ref + '.' + sk.ref)
+ return refs
+ else:
+ return []
+
+
+class CrmlKeyRangeSubKey(_CrmlObjectBase):
+ SIMPLE_EQ_VARNAMES = ['ref', 'name', 'type', 'int']
+
+ def __init__(self, **kwargs):
+ try:
+ self.ref = kwargs['ref']
+ self.type = kwargs['type']
+ self.int = kwargs['int']
+ self.name = kwargs.get('name')
+ except KeyError, e:
+ raise ValueError("Mandatory argument '%s' not given!" % e.message)
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,206 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from cone.public import exceptions, plugin
+import crml_impl
+from crml_model import *
+
+
+def get_required_attr(elem, attrname):
+ """
+ Get a required attribute from an XML element or raise an exception.
+ """
+ attr = elem.get(attrname)
+ if attr is None:
+ raise exceptions.ParseError("<%s> element does not have the required '%s' attribute!" % (elem.tag, attrname))
+ return attr
+
+def convert_num(string):
+ """
+ Convert the given string into a number.
+
+ - The number can be in decimal or hexadecimal format.
+ - If None is passed, None is also returned.
+ """
+ if string in ('', None):
+ return None
+ try:
+ return long(string)
+ except ValueError:
+ return long(string, 16)
+
+class CrmlReader(plugin.ReaderBase):
+ NAMESPACE = 'http://www.s60.com/xml/cenrep/1'
+ FILE_EXTENSIONS = ['crml']
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = CrmlReader()
+ repository = reader.read_repository(etree)
+ return crml_impl.CrmlImpl(resource_ref, configuration, repository)
+
+ def read_repository(self, elem):
+ """
+ Read a CrmlRepository object from the given XML element.
+ """
+ # Read repository attributes
+ repo = CrmlRepository(
+ uid_value = elem.get('uidValue'),
+ uid_name = elem.get('uidName'),
+ owner = elem.get('owner'),
+ version = elem.get('initialisationFileVersion', '1'),
+ access = self.read_access(elem))
+ if elem.get('backup') == 'true': repo.backup = True
+ if elem.get('rfs') == 'true': repo.rfs = True
+
+ # Read all keys
+ for sub_elem in elem:
+ key_obj = self.read_key(sub_elem)
+
+ if key_obj is not None:
+ # Read-only keys have always cap_wr=AlwaysFail.
+ # the isinstance() check is for CT2 output compatibility
+ if not isinstance(key_obj, CrmlKeyRange):
+ if key_obj.read_only:
+ key_obj.access.cap_wr = 'AlwaysFail'
+ key_obj.access.sid_wr = None
+
+ repo.keys.append(key_obj)
+
+ if repo.access == CrmlAccess(cap_rd='AlwaysPass') and len(repo.keys) == 0:
+ repo.access.cap_rd = None
+
+ return repo
+
+ def read_access(self, elem):
+ """
+ Read a CrmlAccess object from the given XML element.
+ @param elem: The element from which to parse an access definition. Should be any
+ element that can contain an access definition (i.e. 'repository', 'key', or 'keyRange').
+ """
+ access = CrmlAccess()
+ read_cap_found = False
+ write_cap_found = False
+ for access_elem in elem.findall('{%s}access' % self.NAMESPACE):
+ type = access_elem.get('type')
+ if type == 'R' and not read_cap_found:
+ access.cap_rd = access_elem.get('capabilities')
+ access.sid_rd = access_elem.get('sid')
+ read_cap_found = True
+ elif type == 'W' and not write_cap_found:
+ access.cap_wr = access_elem.get('capabilities')
+ access.sid_wr = access_elem.get('sid')
+ write_cap_found = True
+
+ return access
+
+ def read_common_key_attrs(self, key_elem, key_obj):
+ """
+ Read common attributes into an object of class CrmlKeyBase from an XML element.
+ """
+ if not isinstance(key_obj, CrmlKeyBase):
+ raise ValueError("Expected object of type %s" % CrmlKeyBase.__name__)
+
+ if key_elem.get('readOnly') == 'true': key_obj.read_only = True
+ if key_elem.get('backup') == 'true': key_obj.backup = True
+ key_obj.access = self.read_access(key_elem)
+ key_obj.name = key_elem.get('name')
+
+ def read_key(self, key_elem):
+ key_obj = None
+ if key_elem.tag == '{%s}key' % self.NAMESPACE:
+ # Determine whether the key is a normal key or a bitmask key
+ # based on the presence of elements
+ tags = [e.tag for e in key_elem]
+ if '{%s}bit' % self.NAMESPACE in tags:
+ key_obj = self.read_bitmask_key(key_elem)
+ else:
+ key_obj = self.read_simple_key(key_elem)
+ elif key_elem.tag == '{%s}keyRange' % self.NAMESPACE:
+ key_obj = self.read_key_range(key_elem)
+
+ return key_obj
+
+ def read_simple_key(self, key_elem):
+ """
+ Read a CrmlSimpleKey object from the given XML element.
+ """
+ expected_tag = '{%s}key' % self.NAMESPACE
+ if key_elem.tag != expected_tag:
+ raise RuntimeError("Incorrect XML element passed to read_simple_key(): %s, expected %s" % (key_elem.tag, expected_tag))
+
+ key = CrmlSimpleKey(
+ ref = get_required_attr(key_elem, 'ref').replace('/', '.'),
+ int = get_required_attr(key_elem, 'int'),
+ type = key_elem.get('type', 'int'))
+ self.read_common_key_attrs(key_elem, key)
+
+ return key
+
+ def read_bitmask_key(self, key_elem):
+ """
+ Read a CrmlBitmaskKey object from the given XML element.
+ """
+ expected_tag = '{%s}key' % self.NAMESPACE
+ if key_elem.tag != expected_tag:
+ raise RuntimeError("Incorrect XML element passed to read_bitmask_key(): %s, expected %s" % (key_elem.tag, expected_tag))
+
+ # Read attributes
+ key = CrmlBitmaskKey(
+ int = get_required_attr(key_elem, 'int'),
+ type = key_elem.get('type', 'int'))
+ self.read_common_key_attrs(key_elem, key)
+
+ # Read bits
+ for bit_elem in key_elem.findall('{%s}bit' % self.NAMESPACE):
+ ref = get_required_attr(bit_elem, 'ref').replace('/', '.')
+ if bit_elem.get('value') == 'false': invert = True
+ else: invert = False
+ index = int(bit_elem.text.strip())
+
+ key.bits.append(CrmlBit(ref=ref, index=index, type=type, invert=invert))
+
+ return key
+
+ def read_key_range(self, key_range_elem):
+ """
+ Read a CrmlKeyRange object from the given XML element.
+ """
+ expected_tag = '{%s}keyRange' % self.NAMESPACE
+ if key_range_elem.tag != expected_tag:
+ raise RuntimeError("Incorrect XML element passed to read_key_range(): %s, expected %s" % (key_range_elem.tag, expected_tag))
+
+ # Read attributes
+ ref = key_range_elem.get('ref')
+ if ref is not None: ref = ref.replace('/', '.')
+ key_range = CrmlKeyRange(
+ ref = ref,
+ first_int = get_required_attr(key_range_elem, "firstInt"),
+ last_int = get_required_attr(key_range_elem, "lastInt"),
+ count_int = key_range_elem.get('countInt'),
+ first_index = convert_num(key_range_elem.get('firstIndex', '0')),
+ index_bits = convert_num(key_range_elem.get('indexBits')))
+ self.read_common_key_attrs(key_range_elem, key_range)
+
+ # Read sub-keys
+ for subkey_elem in key_range_elem.findall('{%s}key' % self.NAMESPACE):
+ ref = get_required_attr(subkey_elem, 'ref').replace('/', '.')
+ int = get_required_attr(subkey_elem, 'int')
+ name = subkey_elem.get('name')
+ type = subkey_elem.get('type', 'int')
+ key_range.subkeys.append(CrmlKeyRangeSubKey(ref=ref, int=int, name=name, type=type))
+
+ return key_range
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_writer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_writer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,574 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import re
+from cone.public import exceptions
+import crml_reader
+from crml_model import *
+
+class CenRepEntry(object):
+ """
+ Class representing an entry in a CenRep text file.
+ """
+ def __init__(self, **kwargs):
+ self.int = kwargs.get('int')
+ self.crml_type = kwargs.get('crml_type')
+ self.confml_type = kwargs.get('confml_type')
+ self.value = kwargs.get('value')
+ self.orig_value = kwargs.get('orig_value')
+ self.access = kwargs.get('access')
+ self.backup = kwargs.get('backup', False)
+
+ @property
+ def metadata(self):
+ return _get_metadata(self.backup)
+
+ def __lt__(self, other):
+ return crml_reader.convert_num(self.int) < crml_reader.convert_num(other.int)
+
+class CenRepRfsRecord(object):
+ """
+ Class representing an entry in the CenRep RFS text file.
+ """
+ def __init__(self, repo_uid, key_uids=None):
+ self.repo_uid = repo_uid
+ self.key_uids = key_uids or []
+
+ def __eq__(self, other):
+ if type(self) == type(other): return self.repo_uid == other.repo_uid
+ else: return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __lt__(self, other):
+ return self.repo_uid < other.repo_uid
+
+ def __repr__(self):
+ return "CenRepRfsRecord(repo_uid=%s, key_uids=%r)" % (self.repo_uid, self.key_uids)
+
+
+class CrmlTxtWriter(object):
+ """
+ Writer class for generating CenRep .txt files based on a CRML model.
+ """
+
+ def __init__(self, configuration, log):
+ self.configuration = configuration
+ self.log = log
+
+ def get_cenrep_txt_data(self, repository):
+ """
+ Return the text data for the CenRep txt generated based on the given
+ CRML repository model.
+ @return: Text data for the CenRep text file.
+ """
+ data = []
+
+ # Generate header lines
+ data.extend(self.get_header_lines(repository))
+
+ self._check_repository_attrs(repository)
+
+ # Generate CenRep entries for all keys
+ cenrep_entries = []
+ for key in repository.keys:
+ cenrep_entries.extend(self.get_cenrep_entries(key))
+
+ # Generate entry lines based on the entries
+ cenrep_entries.sort()
+ for entry in cenrep_entries:
+ data.append(self.get_cenrep_entry_line(entry))
+
+ data.append('')
+
+ # Remove Nones from the line list
+ data = filter(lambda val: val is not None, data)
+
+ return '\r\n'.join(data)
+
+ def get_cenrep_rfs_txt_data(self, rfs_records):
+ """
+ Return the text data for the CenRep RFS txt generated based on the given
+ CenRep RFS record list.
+ """
+ data = []
+
+ # Make a distinct and sorted array of the records
+ records = []
+ for r in rfs_records:
+ if r not in records: records.append(r)
+ records.sort()
+
+ for record in records:
+ repo_uid = record.repo_uid
+
+ # Add padding zeros to the UID
+ if len(repo_uid) < 8:
+ repo_uid = (8 - (len(repo_uid) % 8)) * '0' + repo_uid
+ temp = "CR %s" % repo_uid
+ if record.key_uids:
+ temp += " %s" % ' '.join(record.key_uids)
+ data.append(temp)
+
+ return '\r\n'.join(data)
+
+ def get_cenrep_rfs_record(self, repository):
+ """
+ Return the RFS record for the given CRML repository.
+
+ @return: A CenRepRfsRecord object if the repository should be listed
+ in cenrep_rfs.txt, None if not.
+ """
+ # Get the UID as a hex value without the leading 0x
+ repo_uid = _translate_key_uid(repository.uid_value)[2:]
+
+ # Check if the whole repository has RFS=true
+ if repository.rfs:
+ return CenRepRfsRecord(repo_uid)
+
+ # Collect the UIDs of the keys that should be listed
+ rfs_key_uids = []
+ for key in repository.keys:
+ if self._key_is_rfs(key) and key.int:
+ # Get the UID as a hex value without the leading 0x
+ uid = _translate_key_uid(key.int)[2:]
+ rfs_key_uids.append(uid)
+
+ if rfs_key_uids:
+ return CenRepRfsRecord(repo_uid, rfs_key_uids)
+ else:
+ return None
+
+ def _key_is_rfs(self, key):
+ """
+ @return: True if the key UID should be listed in cenrep_rfs.txt
+ """
+ if isinstance(key, CrmlSimpleKey):
+ return bool(self._get_rfs_value(key.ref))
+ elif isinstance(key, CrmlBitmaskKey):
+ for bit in key.bits:
+ if self._get_rfs_value(bit.ref):
+ return True
+ else:
+ return False
+
+ def _get_rfs_value(self, ref):
+ """
+ @return: The RFS value for the given setting, or None if not available.
+ """
+ if ref is None: return
+
+ try:
+ feature = self._get_feature(ref)
+ except exceptions.NotFound:
+ # Feature not found in the configuration
+ return None
+
+ return feature.get_value(attr='rfs')
+
+ def get_header_lines(self, repository):
+ """
+ Return a list of lines to be written in the header section of the CenRep text file.
+ """
+ data = ['cenrep',
+ 'version %s' % repository.version]
+
+ if repository.owner:
+ data.append('[owner]')
+ data.append(repository.owner)
+
+ data.append('[defaultmeta]')
+ data.append(' %d' % _get_metadata(repository.backup))
+ for key in repository.keys:
+ data.append(self.get_defaultmeta_line(key))
+
+ data.append('[platsec]')
+ acc_text = self.get_access_line(repository.access)
+ if acc_text: acc_text = ' ' + acc_text
+ data.append(acc_text)
+ for key in repository.keys:
+ data.append(self.get_platsec_line(key, repository))
+
+
+ data.append('[Main]')
+ return data
+
+ def get_cenrep_entries(self, key):
+ """
+ Generate CenRep entries based on the given CRML key object.
+ @return: A list of CenRepEntry objects.
+ """
+ if isinstance(key, CrmlSimpleKey):
+ feature = self._get_feature(key.ref)
+ entry = CenRepEntry(int = key.int,
+ crml_type = key.type,
+ confml_type = feature.get_type(),
+ value = feature.get_value(),
+ orig_value = feature.get_original_value(),
+ backup = key.backup,
+ access = key.access)
+ return [entry]
+ elif isinstance(key, CrmlBitmaskKey):
+ return self.get_bitmask_key_cenrep_entries(key)
+ elif isinstance(key, CrmlKeyRange):
+ return self.get_key_range_cenrep_entries(key)
+ else:
+ raise TypeError("Unsupported CRML key object type %s" % type(key))
+
+ def get_key_range_cenrep_entries(self, key_range):
+ """
+ Generate CenRep entries based on the given CrmlKeyRange object.
+ @return: A list of CenRepEntry objects.
+ """
+ entries = []
+ count = 0
+
+ # Generate the countInt entry if necessary
+ if key_range.count_int is not None and key_range.ref is not None:
+ try:
+ feature = self._get_feature(key_range.ref)
+
+ # For CT2 output compatibility
+ if feature.get_type() != 'sequence':
+ return []
+
+ values = feature.get_value()
+ except exceptions.NotFound:
+ values = []
+
+ count = len(values)
+
+ entry = CenRepEntry(int = key_range.count_int,
+ crml_type = 'int',
+ confml_type = 'int',
+ value = count,
+ backup = key_range.backup,
+ access = key_range.access)
+ entries.append(entry)
+
+ # Generate entries based on the sequence values
+ for subkey in key_range.subkeys:
+ full_ref = "%s.%s"% (key_range.ref, subkey.ref)
+
+ try:
+ feature = self._get_feature(full_ref)
+ values = feature.get_value()
+ confml_type = feature.get_type()
+ backup = key_range.backup
+ except exceptions.NotFound:
+ # For CT2 output compatibility
+ values = ['null' for i in xrange(count)]
+ confml_type = None
+ backup = False
+
+ for i, value in enumerate(values):
+ # Calculate the index of the entry
+ index = self.get_index(crml_reader.convert_num(key_range.first_int),
+ crml_reader.convert_num(key_range.first_index),
+ crml_reader.convert_num(key_range.index_bits),
+ i,
+ crml_reader.convert_num(subkey.int))
+
+ entry = CenRepEntry(int = "0x%x" % index,
+ crml_type = subkey.type,
+ confml_type = confml_type,
+ value = value,
+ orig_value = value,
+ backup = backup,
+ access = key_range.access)
+ entries.append(entry)
+
+ return entries
+
+ def get_bitmask_key_cenrep_entries(self, key):
+ """
+ Generate CenRep entries based on the given CrmlBitmaskKey object.
+ @return: A list of CenRepEntry objects.
+ """
+ # Calculate the value based on the bit values
+ # -------------------------------------------
+ value = 0
+ for bit in key.bits:
+ feature = self._get_feature(bit.ref)
+ bit_value = feature.get_value()
+ if bit.invert: bit_value = not bit_value
+ if bit_value: value |= 1 << (bit.index - 1)
+
+ # Generate the textual representation of the bitmask value.
+ # This is done at this point because in get_cenrep_entry_line()
+ # we don't know anymore if the key was a bitmask key or a
+ # simple key.
+ # -------------------------------------------------------------
+ if key.type == 'binary':
+ orig_value = "%X" % value
+ # Add padding zeroes so that the number of digits
+ # is divisible by 8 (done manually since the length
+ # of a binary bitmask is unbounded).
+ padding_zeroes = (8 - len(orig_value) % 8) * '0'
+ # 4 is a special case for CT2 output compatibility
+ if len(orig_value) != 4:
+ orig_value = padding_zeroes + orig_value
+ else:
+ orig_value = str(value)
+
+ entry = CenRepEntry(int = key.int,
+ crml_type = key.type,
+ confml_type = 'int',
+ value = value,
+ orig_value = orig_value,
+ backup = key.backup,
+ access = key.access)
+ return [entry]
+
+ def get_defaultmeta_line(self, key):
+ """
+ Return the defaultmeta section line for the given CRML key object.
+ """
+ if not isinstance(key, CrmlKeyRange): return None
+
+ return "%s %s %d" % (key.first_int,
+ key.last_int,
+ _get_metadata(key.backup))
+
+ def get_platsec_line(self, key, repository):
+ """
+ Return the platsec section line for the given CRML key object.
+ """
+ if not isinstance(key, CrmlKeyRange): return None
+
+ # In a key range platsec entry something must be present, so if
+ # the access object is empty, use cap_rd and cap_wr from the repository's
+ # global access definition
+ access = key.access.copy()
+ is_empty = True
+ for attrname in ('sid_rd', 'cap_rd', 'sid_wr', 'cap_wr'):
+ if getattr(access, attrname) not in ('', None):
+ is_empty = False
+ if is_empty:
+ access.cap_rd = repository.access.cap_rd
+ access.cap_wr = repository.access.cap_wr
+
+ acc_text = self.get_access_line(access)
+ if acc_text: acc_text = ' ' + acc_text
+
+ return "%s %s%s" % (key.first_int,
+ key.last_int,
+ acc_text)
+
+
+ def get_cenrep_entry_line(self, entry):
+ """
+ Return the text line for a CenRepEntry object.
+ """
+ value = None
+ if entry.crml_type in ('string', 'string8'):
+ if entry.confml_type is None:
+ pass
+ else:
+ if entry.orig_value is None:
+ value = '""'
+ else:
+ value = '"%s"' % entry.orig_value
+ elif entry.crml_type == 'int':
+ if entry.confml_type == 'boolean':
+ if entry.value: value = '1'
+ else: value = '0'
+ else:
+ value = entry.orig_value
+ elif entry.crml_type == 'real':
+ value = entry.orig_value or ''
+ elif entry.crml_type == 'binary':
+ # Empty binary values are denoted by a single dash
+ value = entry.orig_value or '-'
+
+ if value != '-':
+ # Make sure that the number of digits is divisible by two
+ if len(value) % 2 != 0:
+ value = '0' + value
+
+ if value is None:
+ value = unicode(entry.value)
+
+ self._check_value(entry, value)
+
+ acc_text = self.get_access_line(entry.access)
+ if acc_text: acc_text = ' ' + acc_text
+
+ return '%s %s %s %d%s' % (_translate_key_uid(entry.int),
+ entry.crml_type,
+ value,
+ entry.metadata,
+ acc_text)
+ def _check_value(self, entry, value):
+ """
+ Check that the given value is valid for the given CenRep entry,
+ and log a warning if it is not.
+ """
+ if entry.crml_type == 'int':
+ # Check if the value is a string, since it may already
+ # be an integer
+ if not isinstance(value, basestring):
+ return
+
+ try:
+ value = value.strip()
+ if value.lower().startswith('0x'):
+ long(value, 16)
+ else:
+ long(value)
+ except ValueError:
+ self.log.warn("Key %s: Invalid integer value '%s'" % (entry.int, value))
+ elif entry.crml_type == 'real':
+ try:
+ float(value)
+ except ValueError:
+ self.log.warn("Key %s: Invalid real value '%s'" % (entry.int, value))
+ elif entry.crml_type == 'binary':
+ if value != '-' and re.match(r'^(0[xX])?[0-9a-fA-F]+$', value) is None:
+ self.log.warn("Key %s: Invalid binary value '%s'" % (entry.int, value))
+
+ def _check_repository_attrs(self, repository):
+ """
+ Check that the attributes of the given repository are valid and
+ log warnings if not.
+ """
+ if repository.owner is not None:
+ owner = repository.owner.strip()
+ # An empty owner UID is OK, it doesn't generate anything
+ # invalid into the output
+ if owner != '':
+ try:
+ if owner.lower().startswith('0x'):
+ long(owner, 16)
+ else:
+ long(owner)
+ except ValueError:
+ self.log.warn("Invalid owner UID '%s'" % owner)
+
+ def get_access_line(self, access):
+ """
+ Generate a line containing access information based on a CrmlAccess object.
+ """
+ # Write the access information in a specific order, because it
+ # won't work otherwise
+ var_order = ['sid_rd', 'cap_rd', 'sid_wr', 'cap_wr']
+ data = []
+ for varname in var_order:
+ val = getattr(access, varname)
+ if val not in ('', None):
+ # Using _translate_capability_string() on all, since a SID should
+ # not contain anything that could be messed up by the function
+ data.append('%s=%s' % (varname, _translate_capability_string(val)))
+
+ return ' '.join(data)
+
+ def _get_feature(self, ref):
+ return self.configuration.get_default_view().get_feature(ref)
+
+ @classmethod
+ def get_index(cls,firstInt,firstIndex,indexBits,seqIndex, subIndex):
+ """
+ @param firstIndex: The first value available in the keyrange
+ @param lastInt: The last value available in the keyrange
+ @param indexBits: The index bits or mask for sequence index
+ @param seqIndex: The sequence index
+ @param subIndex: The sequence sub element index
+ @return: an numeric value for the encoded index
+ """
+ rangeshift = cls.get_range_shift(indexBits)
+ return (((seqIndex+firstIndex) << rangeshift) + firstInt) + subIndex
+
+ @classmethod
+ def get_seqid(cls,firstInt,firstIndex,indexBits,cenrepkey):
+ """
+ @param firstIndex: The first value available in the keyrange
+ @param lastInt: The last value available in the keyrange
+ @param indexBits: The index bits or mask for sequence index
+ @param cenrepkey: Crml key id
+ @return: an numeric value for the encoded index
+ """
+ rangeshift = cls.get_range_shift(indexBits)
+ return (((cenrepkey & indexBits) -firstInt) >> rangeshift)-firstIndex
+
+ @classmethod
+ def get_subseqid(cls,firstInt,firstIndex,indexBits,cenrepkey):
+ """
+ @param firstIndex: The first value available in the keyrange
+ @param lastInt: The last value available in the keyrange
+ @param indexBits: The index bits or mask for sequence index
+ @param cenrepkey: Crml key id
+ @return: an numeric value for the encoded index
+ """
+ range = cls.get_range(indexBits)
+ return (cenrepkey - firstInt) & range
+
+ @classmethod
+ def get_range_shift(cls,indexBits):
+ """ Get the bit left to the """
+ seqrange = cls.get_range(indexBits)
+ shiftamount = 0
+ for i in range(0,32):
+ if (seqrange >> i) == 0:
+ shiftamount = i
+ break
+ return shiftamount
+
+ @classmethod
+ def get_range(cls,indexBits):
+ """ Get the bit left to the """
+ indexshift = 0
+ for i in range(0,32):
+ if (indexBits >> i) == 0:
+ indexshift = i
+ break
+ return ((0x1 << indexshift) - indexBits)-1
+
+
+# =============================================================================
+# Utility functions
+# =============================================================================
+
+def _get_metadata(backup):
+ metadata = 0
+ if backup: metadata |= 0x1000000
+ return metadata
+
+def _translate_key_uid(uid):
+ """Translate a key UID given in CRML so that it matches the output of CT2."""
+ if uid.lower().startswith("0x"):
+ prefix = uid[:2]
+ temp = uid[2:]
+ if int(temp, 16) == 0: return prefix + "0"
+ else: return prefix + uid[2:].lstrip('0')
+ else:
+ if int(uid) == 0: return "0"
+ else: return uid.lstrip('0')
+
+def _translate_capability_string(cap_str):
+ """
+ Translate a capability string so that it is
+ suitable for writing to a CenRep txt file.
+ """
+ cap_str = cap_str.replace('AlwaysPass', 'alwayspass').replace('AlwaysFail', 'alwaysfail')
+
+ # The capability string can be a list separated either by
+ # whitespace or commas
+ if ',' in cap_str: caps = cap_str.split(',')
+ else: caps = cap_str.split()
+
+ # The output must always be comma-separated
+ return ','.join(caps)
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+SCRIPTS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../../..', "scripts"))
+assert os.path.exists(SCRIPTS_ROOT)
+os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + SCRIPTS_ROOT + ';' + PLUGINS_ROOT
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/centrepconv_txt_to_cre.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/centrepconv_txt_to_cre.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,205 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Helper script for running CentRepConv.exe to convert .txt files to
+# .cre files. The script is given a drive where an S60 environment is
+# substed and it handles all necessary input/output file moving and
+# command running to do the conversion.
+#
+# The .txt files for which the conversion fails are reported at the end
+# of the conversion.
+#
+
+import sys, os, subprocess, shutil, re
+import logging
+from optparse import OptionParser, OptionGroup
+
+log = logging.getLogger()
+
+# Paths to the temporary directories on the environment level
+TEMP_INPUT_DIR = r'\epoc32\WINSCW\C\cenrepconv_temp\input'
+TEMP_OUTPUT_DIR = r'\epoc32\WINSCW\C\cenrepconv_temp\output'
+
+# The same temporary directories in the form the emulator sees them
+TEMP_INPUT_DIR_EMULATOR = r'C:\cenrepconv_temp\input'
+TEMP_OUTPUT_DIR_EMULATOR = r'C:\cenrepconv_temp\output'
+
+def recreate_dir(dir):
+ if os.path.exists(dir):
+ shutil.rmtree(dir)
+ os.makedirs(dir)
+
+def find_cenrep_txt_files(dir):
+ """
+ Find all CenRep txt files in the given directory.
+ @return: List of absolute paths to the files.
+ """
+ pattern = re.compile(r'^[a-fA-F0-9]{8}\.txt$')
+ dir = os.path.abspath(dir)
+
+ result = []
+ for root, dirs, files in os.walk(dir):
+ for file in files:
+ if pattern.match(file) is not None:
+ result.append(os.path.join(root, file))
+ return result
+
+def convert_txt_to_cre(file_path, output_dir):
+ """
+ Convert a CenRep .txt file into a .cre file using CentRepConv.exe.
+ @param file_path: Path to the .txt file.
+ @param output_dir: Directory where the resulting .cre file will be copied.
+ If None, the output file will not be copied anywhere.
+ @return: True if conversion was OK and the corresponding .cre file was
+ created, False if not.
+ """
+ output_dir = os.path.abspath(output_dir)
+ file_path = os.path.abspath(file_path)
+ filename = os.path.basename(file_path)
+ filename_out = filename[:-4] + '.cre'
+
+ # Copy the input file into place
+ temp_input_file = os.path.join(TEMP_INPUT_DIR, filename)
+ shutil.copy2(file_path, temp_input_file)
+
+ # Run the conversion
+ cmd = r'\epoc32\release\WINSCW\udeb\centrepconv.exe -dNoGui -dtextshell -Mconsole -- -o %s %s' \
+ % (os.path.join(TEMP_OUTPUT_DIR_EMULATOR, filename_out), os.path.join(TEMP_INPUT_DIR_EMULATOR, filename))
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
+ out, err = p.communicate()
+ if p.returncode != 0:
+ log.debug("Failed to execute command: %s" % cmd)
+ log.debug("Command output:\n%s", out)
+ return False
+
+ temp_output_file = os.path.join(TEMP_OUTPUT_DIR, filename_out)
+ if not os.path.exists(temp_output_file):
+ log.debug("Expected output file '%s' does not exist" % temp_output_file)
+ return False
+
+ # Copy to output if necessary
+ if output_dir:
+ if not os.path.exists(output_dir):
+ os.makedirs(output_dir)
+ output_file = os.path.join(output_dir, os.path.basename(temp_output_file))
+ log.debug("Copying output file to '%s'" % output_file)
+ shutil.copy2(temp_output_file, output_file)
+
+ log.debug("Removing temp output file '%s'" % temp_output_file)
+ os.remove(temp_output_file)
+ return True
+
+def main():
+ parser = OptionParser()
+
+ parser.add_option("--env-drive",
+ help="Specifies the drive where the S60 environment containing CentRepConv.exe is located. Note that the drive needs to be writable, since input/output files need to be moved there in order to make the conversion work. Example: 'X:'",
+ metavar="DRIVE")
+
+ parser.add_option("--input-file",
+ help="Specifies a single CenRep .txt file to convert.",
+ metavar="FILE")
+
+ parser.add_option("--input-dir",
+ help="Specifies a directory containing the CenRep .txt files to convert. Only CenRep .txt files converted.",
+ metavar="FILE")
+
+ parser.add_option("--output",
+ help="The directory where the resulting .cre files are generated",
+ metavar="DIR")
+
+ parser.add_option("--validate",
+ action="store_true",
+ help="Don't copy output files to --output, only check if a .cre file is generated for each .txt file.",
+ default=False)
+
+ parser.add_option("-v", "--verbose",
+ action="store_true",
+ help="Show debug information",
+ default=False)
+
+ (options, args) = parser.parse_args()
+
+ if not options.env_drive:
+ parser.error("--env-drive must be specified")
+ if re.match('^[A-Za-z]:$', options.env_drive) is None:
+ parser.error("Invalid --env-drive '%s', should be e.g. 'X:'" % options.env_drive)
+ if not os.path.exists(options.env_drive):
+ parser.error("Specified --env-drive '%s' does not exist" % options.env_drive)
+
+ if not options.input_file and not options.input_dir:
+ parser.error("--input-file or --input-dir must be specified")
+ if options.input_file and options.input_dir:
+ parser.error("Only one for --input-file and --input-dir may be specified")
+ if options.input_file and not os.path.isfile(options.input_file):
+ parser.error("Specified --input-file does not exist or is not a file")
+ if options.input_dir and not os.path.isdir(options.input_dir):
+ parser.error("Specified --input-dir does not exist or is not a directory")
+
+ if not options.output and not options.validate:
+ parser.error("Either --output or --validate must be specified")
+
+ if options.verbose: log_level = logging.DEBUG
+ else: log_level = logging.INFO
+ logging.basicConfig(format="%(levelname)-8s: %(message)s", stream=sys.stdout, level=log_level)
+
+ if options.output: output_dir = os.path.abspath(options.output)
+ else: output_dir = None
+
+ # Find input files
+ log.info("Determining input files")
+ if options.input_file:
+ input_files = [os.path.abspath(options.input_file)]
+ else:
+ input_files = find_cenrep_txt_files(options.input_dir)
+ log.info("%d input file(s)" % len(input_files))
+
+ if len(input_files) == 0:
+ log.info("No input files")
+ return
+
+ log.debug("Changing working directory to '%s'" % options.env_drive)
+ os.chdir(options.env_drive)
+
+ log.debug("Creating/cleaning temporary output directory '%s'" % TEMP_OUTPUT_DIR)
+ recreate_dir(TEMP_OUTPUT_DIR)
+ log.debug("Creating/cleaning temporary input directory '%s'" % TEMP_INPUT_DIR)
+ recreate_dir(TEMP_INPUT_DIR)
+
+ log.info("Running conversion")
+ failed_files = []
+ PROGRESS_STEP_PERCENTAGE = 5.0
+ ratio = 100.0 / float(len(input_files))
+ last_percentage = 0
+ for i, file in enumerate(input_files):
+ percentage = ratio * float(i)
+ if percentage - last_percentage > PROGRESS_STEP_PERCENTAGE:
+ log.info("%d%%" % percentage)
+ last_percentage = percentage
+
+ log.debug("Converting '%s'" % file)
+ ok = convert_txt_to_cre(file, output_dir)
+ if not ok:
+ log.debug("Conversion of '%s' failed" % file)
+ failed_files.append(file)
+
+ if failed_files:
+ print "Conversion failed for %d file(s)" % len(failed_files)
+ prefix = os.path.commonprefix(failed_files)
+ print "Common prefix: %s" % prefix
+ for file in failed_files:
+ print file[len(prefix):]
+
+if __name__ == "__main__":
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000001_simple_keys.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000001_simple_keys.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000002_bitmask_keys.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000002_bitmask_keys.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+
+ 4
+
+
+
+ 1
+ 2
+
+
+
+ 1
+ 2
+ 3
+
+ 4
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000003_key_ranges.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000003_key_ranges.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000004_key_type_changed.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000004_key_type_changed.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ 1
+
+
+
+
+ 1
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000005_repo_attrs_changed.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000005_repo_attrs_changed.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000006_renamed_repo.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/00000006_renamed_repo.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/10000001_removed_repo.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/10000001_removed_repo.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/30000000_duplicate_repo1_proj1.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/30000000_duplicate_repo1_proj1.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/30000000_duplicate_repo2_proj1.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/implml/30000000_duplicate_repo2_proj1.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/Layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/root.confml
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_1/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000001_simple_keys.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000001_simple_keys.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000002_bitmask_keys.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000002_bitmask_keys.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+
+ 5
+
+
+
+ 1
+ 2
+
+
+
+ 1
+ 2
+ 3
+
+ 5
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000003_key_ranges.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000003_key_ranges.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000004_key_type_changed.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000004_key_type_changed.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000005_repo_attrs_changed.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000005_repo_attrs_changed.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000006_renamed_repo_xyz.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/00000006_renamed_repo_xyz.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/20000001_added_repo.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/20000001_added_repo.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/30000000_duplicate_repo1_proj2.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/30000000_duplicate_repo1_proj2.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/30000000_duplicate_repo2_proj2.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/implml/30000000_duplicate_repo2_proj2.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/Layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/root.confml
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/comp_project_2/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000001.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000001.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000002.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000002.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000003.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000003.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000004.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000004.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000005.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/10000005.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/private/100059C9/cenrep_rfs.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_expected/private/100059C9/cenrep_rfs.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/all_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/all_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/backup_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/backup_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/bitmask_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/bitmask_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 1
+ 1
+ 0
+
+ 1
+ 0
+ 0
+ 1
+
+
+
+
+
+ false
+ false
+ false
+ false
+
+ false
+ true
+ false
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/no_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/no_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+ false
+ false
+ false
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/partial_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/partial_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+ true
+ false
+ true
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/repo_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/confml/repo_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+
+ true
+ false
+ true
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000001_all_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000001_all_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000001_all_rfs_dup.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000001_all_rfs_dup.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000002_partial_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000002_partial_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000002_partial_rfs_dup.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000002_partial_rfs_dup.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000003_no_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000003_no_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000003_no_rfs_dup.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000003_no_rfs_dup.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000004_repo_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000004_repo_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000004_repo_rfs_dup.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000004_repo_rfs_dup.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000005_bitmask_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000005_bitmask_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000005_bitmask_rfs_dup.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/implml/1000005_bitmask_rfs_dup.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/Layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/root.confml
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/duplicate_rfs_project/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000001.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000001.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000002.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000002.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000003.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000003.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000004.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000004.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000005.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000005.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000006.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000006.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000007.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000007.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000008.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000008.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000009.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/00000009.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000A.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000A.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000B.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000B.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000C.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000C.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000D.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000D.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000E.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000E.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E1.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E1.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E2.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E2.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E3.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E3.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E4.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E4.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E5.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E5.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E6.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E6.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E7.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E7.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E8.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E8.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E9.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000E9.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000EA.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000EA.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000F1.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/000000F1.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000001.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000001.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000002.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000002.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000003.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000003.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000004.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000004.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000005.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/10000005.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/20000001.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/20000001.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/private/100059C9/cenrep_rfs.txt
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/private/100059C9/cenrep_rfs.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/access_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/access_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/access_test_2.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/access_test_2.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+
+
+
+ Test setting 1
+
+
+ Test setting 2
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/all_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/all_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/backup_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/backup_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/bitmask_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/bitmask_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 1
+ 1
+ 0
+
+ 1
+ 0
+ 0
+ 1
+
+
+
+
+
+ false
+ false
+ false
+ false
+
+ false
+ true
+ false
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/bitmask_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/bitmask_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,260 @@
+
+
+
+ Feature with bitmask flags
+
+ A boolean setting for bit 0
+
+
+ A boolean setting for bit 1
+
+
+ A boolean setting for bit 2
+
+
+ A boolean setting for bit 3
+
+
+ A boolean setting for bit 4
+
+
+ A boolean setting for bit 5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ false
+ true
+ false
+ true
+ false
+
+ false
+ true
+ false
+ true
+
+ false
+ true
+ true
+ false
+ true
+ false
+ true
+ false
+ true
+ true
+ 1
+ 0
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 0
+ 1
+ 1
+ 0
+ 1
+ 0
+ 1
+ 1
+ 0
+
+ 1
+ true
+ 1
+ true
+ 1
+
+ true
+ 1
+ false
+ true
+ 0
+ true
+ 1
+ true
+ 1
+ true
+ 1
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 1
+
+ 0
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/booleans.confml
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/booleans.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_binaries.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_binaries.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10
+ B371C72F3D82C38D9B8C7AAD8BF542BD
+ 1
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_ints.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_ints.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10
+ 1
+ 0xA
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_reals.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_reals.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+
+ 1.2345
+ 0.0000
+ 0
+ 1.5
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_strings.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_strings.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10
+ true
+ 11.3
+ älämölö カタカナ <&> \"
+ opt3
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_strings8.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/crml_strings8.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10
+ true
+ 11.3
+ älämölö カタカナ <&> \"
+ opt3
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,99 @@
+
+
+
+ Feature with all setting types
+
+ A folder setting
+
+
+ A real setting
+
+
+ A file setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A folder sub-setting
+
+
+ A real sub-setting
+
+
+ A file sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ default_folder
+ 3.14
+ default_file.txt
+ 10
+ default string
+ true
+ 1
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ false
+ 1
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/feature2.confml
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/key_range.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/key_range.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ true
+ 1
+
+
+ seq/def3_folder
+ 1.75
+ seq/def3_file.txt
+ 512
+ def3
+ 1
+ 3
+
+
+
+
+
+
+
+ template
+
+
+ test 1
+
+
+ test 2
+
+
+
+ template
+
+
+ test 1
+
+
+ test 2
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/key_range_2.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/key_range_2.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x10285AA9
+ 0
+ 127.0.0.1
+ 20080514:134400.000000
+
+
+ 0x10285AA9
+ 0
+ 127.0.0.1
+ 20080514:134400.000000
+
+
+ 0x10285AA9
+ 1
+ 127.0.0.1
+ 20080514:134400.000000
+
+
+ 0x10285AA9
+ 1
+ 127.0.0.1
+ 20080514:134400.000000
+
+
+ 0x10285AA9
+ 1
+ 127.0.0.1
+ 20080514:134400.000000
+
+
+ 0x10285AA9
+ 1
+ 127.0.0.1
+ 20080514:134400.000000
+
+
+ 0x10285AA9
+ 1
+ 127.0.0.1
+ 20080514:134400.000000
+
+
+
+
+
+ false
+
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+ false
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/no_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/no_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+ false
+ false
+ false
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/partial_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/partial_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+ true
+ false
+ true
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/repo_rfs.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/repo_rfs.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+
+
+
+
+
+
+ true
+ false
+ true
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/sequence_with_rfs_test.confml
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/sequence_with_rfs_test.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/special_char_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/confml/special_char_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ älämölö
+ ударениÑ
+ ελληνικά
+ カタカナ
+ ä¸åœ‹è©±
+ <&>
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000001_feature1.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000001_feature1.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000002_feature2.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000002_feature2.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000003_bitmask_test.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000003_bitmask_test.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+
+
+
+
+ 1
+ 7
+ 18
+ 24
+ 31
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+
+
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+
+
+
+ 1
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000004_booleans.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000004_booleans.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000005_crml_ints.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000005_crml_ints.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000006_crml_reals.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000006_crml_reals.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000007_crml_strings.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000007_crml_strings.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000008_crml_strings8.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000008_crml_strings8.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000009_crml_binaries.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/00000009_crml_binaries.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000A_access_test.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000A_access_test.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000B_backup_test.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000B_backup_test.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000C_key_range.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000C_key_range.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ History items
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000D_sequence_with_rfs_test.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000D_sequence_with_rfs_test.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000E_key_range_2.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/0000000E_key_range_2.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E1_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E1_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E2_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E2_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E3_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E3_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E4_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E4_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E5_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E5_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E6_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E6_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E7_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E7_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E8_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E8_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E9_empty_repository.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000E9_empty_repository.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000EA_empty_repository_ver2.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000EA_empty_repository_ver2.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000F1_access_test_2.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/000000F1_access_test_2.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000001_all_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000001_all_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000002_partial_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000002_partial_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000003_no_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000003_no_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000004_repo_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000004_repo_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000005_bitmask_rfs.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/1000005_bitmask_rfs.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/20000001_special_char_test.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/20000001_special_char_test.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/root.confml
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_comparator.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_comparator.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,248 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import __init__
+from cone.public import plugin
+from CRMLPlugin.crml_model import *
+from CRMLPlugin.crml_comparator import CrmlComparator
+from cone.public.plugin import FlatComparisonResultEntry as Entry
+
+class TestComparator(unittest.TestCase):
+ def setUp(self):
+ keys = [
+ CrmlSimpleKey(ref='Foo.Bar', int='0x1'),
+ CrmlBitmaskKey(int='0x2', bits=[CrmlBit(ref='Foo.Bit1', index=1),
+ CrmlBit(ref='Foo.Bit2', index=2),
+ CrmlBit(ref='Foo.Bit4', index=4, invert=True)]),
+ CrmlKeyRange(first_int='0x10000000', last_int='0x1FFFFFFF', ref="Foo.Seq",
+ subkeys=[CrmlKeyRangeSubKey(ref='Sub1', name='Sub-key 1', type='int', int='0x1'),
+ CrmlKeyRangeSubKey(ref='Sub2', name='Sub-key 2', type='real', int='0x2')]),
+ ]
+
+ self.repo = CrmlRepository(
+ uid_value = '0x10203040',
+ uid_name = 'KCrUidTest',
+ owner = '0x11223344',
+ backup = True,
+ rfs = True,
+ access = CrmlAccess(),
+ keys = keys)
+
+ self.comparator = CrmlComparator('test.crml', self.repo)
+
+
+ def assert_comparison_result_after_change_equals(self,
+ modification_code, added=[], removed=[], modified=[],
+ check_keys_in_entry_data=True,
+ target_resource_ref='test.crml'):
+ # Make a copy of the test repo and modify it using the given code
+ repo = self.repo.copy()
+ exec(modification_code)
+
+ expected_result = plugin.FlatComparisonResult(only_in_source = removed,
+ only_in_target = added,
+ modified = modified)
+
+ comparator = CrmlComparator('test.crml', self.repo)
+ actual_result = comparator.flat_compare(target_resource_ref, repo)
+ self.assertEquals(expected_result, actual_result)
+
+ # Assert that all comparison result entries have references to the
+ # repository objects
+ for entry in actual_result.only_in_source:
+ self.assertTrue(isinstance(entry.data['repo'], CrmlRepository))
+ for entry in actual_result.only_in_target:
+ self.assertTrue(isinstance(entry.data['repo'], CrmlRepository))
+ for entry in actual_result.modified:
+ self.assertTrue(isinstance(entry.data['source_repo'], CrmlRepository))
+ self.assertTrue(isinstance(entry.data['target_repo'], CrmlRepository))
+
+ # Check also references to CRML key objects if specified
+ if check_keys_in_entry_data:
+ for entry in actual_result.only_in_source:
+ self.assertTrue(isinstance(entry.data['key'], CrmlKeyBase))
+ for entry in actual_result.only_in_target:
+ self.assertTrue(isinstance(entry.data['key'], CrmlKeyBase))
+ for entry in actual_result.modified:
+ self.assertTrue(isinstance(entry.data['source_key'], CrmlKeyBase))
+ self.assertTrue(isinstance(entry.data['target_key'], CrmlKeyBase))
+
+ def test_simple_key_changed(self):
+ def check(attrname, value_id, old_value, new_value):
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[0].%s = %r' % (attrname, new_value),
+ modified=[Entry(sub_id = '0x00000001',
+ value_id = value_id,
+ source_value = old_value,
+ target_value = new_value)])
+
+ check('ref', 'ref', 'Foo.Bar', 'Foo.Baz')
+ check('name', 'name', None, 'Foobar')
+ check('backup', 'backup', False, True)
+ check('read_only', 'read_only', False, True)
+ check('access.cap_rd', 'cap_rd', None, 'FooCapability')
+ check('access.cap_wr', 'cap_wr', None, 'FooCapability')
+ check('access.sid_rd', 'sid_rd', None, '0x12345678')
+ check('access.sid_wr', 'sid_wr', None, '0x12345678')
+
+
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[0].int = "0x5"',
+ added = [Entry(sub_id='0x00000005')],
+ removed = [Entry(sub_id='0x00000001')])
+
+ def test_bitmask_key_changed(self):
+ def check(attrname, value_id, old_value, new_value):
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[1].%s = %r' % (attrname, new_value),
+ modified=[Entry(sub_id = '0x00000002',
+ value_id = value_id,
+ source_value = old_value,
+ target_value = new_value)])
+
+ check('name', 'name', None, 'Foobar')
+ check('backup', 'backup', False, True)
+ check('read_only', 'read_only', False, True)
+ check('access.cap_rd', 'cap_rd', None, 'FooCapability')
+ check('access.cap_wr', 'cap_wr', None, 'FooCapability')
+ check('access.sid_rd', 'sid_rd', None, '0x12345678')
+ check('access.sid_wr', 'sid_wr', None, '0x12345678')
+
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[1].int = "0x5"',
+ added = [Entry(sub_id='0x00000005')],
+ removed = [Entry(sub_id='0x00000002')])
+
+ def test_bitmask_key_bit_changed(self):
+ def check(attrname, value_id, old_value, new_value):
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[1].bits[0].%s = %r' % (attrname, new_value),
+ modified = [Entry(sub_id = '0x00000002 (bit 1)',
+ value_id = value_id,
+ source_value = old_value,
+ target_value = new_value)])
+
+ check('ref', 'ref', 'Foo.Bit1', 'Foo.Bar.Bit')
+ check('invert', 'invert', False, True)
+
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[1].bits[0].index = 6',
+ added = [Entry(sub_id='0x00000002 (bit 6)')],
+ removed = [Entry(sub_id='0x00000002 (bit 1)')])
+
+
+ def test_key_range_changed(self):
+ def check(attrname, value_id, old_value, new_value):
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[2].%s = %r' % (attrname, new_value),
+ modified=[Entry(sub_id = '0x10000000-0x1FFFFFFF',
+ value_id = value_id,
+ source_value = old_value,
+ target_value = new_value)])
+
+ check('ref', 'ref', 'Foo.Seq', 'Foo.Bar')
+ check('name', 'name', None, 'Foobar')
+ check('backup', 'backup', False, True)
+ check('read_only', 'read_only', False, True)
+ check('access.cap_rd', 'cap_rd', None, 'FooCapability')
+ check('access.cap_wr', 'cap_wr', None, 'FooCapability')
+ check('access.sid_rd', 'sid_rd', None, '0x12345678')
+ check('access.sid_wr', 'sid_wr', None, '0x12345678')
+
+ def check(attrname, new_value, old_id, new_id):
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[2].%s = %r' % (attrname, new_value),
+ added = [Entry(sub_id=new_id)],
+ removed = [Entry(sub_id=old_id)])
+
+ check('first_int', '0x00000000', '0x10000000-0x1FFFFFFF', '0x00000000-0x1FFFFFFF')
+ check('last_int', '0x20000000', '0x10000000-0x1FFFFFFF', '0x10000000-0x20000000')
+
+ def test_key_range_subkey_changed(self):
+ def check(attrname, old_value, new_value):
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[2].subkeys[0].%s = %r' % (attrname, new_value),
+ modified = [Entry(sub_id = '0x10000000-0x1FFFFFFF (sub-key 0x00000001)',
+ value_id = attrname,
+ source_value = old_value,
+ target_value = new_value)])
+
+ check('ref', 'Sub1', 'FooSub')
+ check('name', 'Sub-key 1', 'Foo')
+ check('type', 'int', 'real')
+
+ self.assert_comparison_result_after_change_equals(
+ 'repo.keys[2].subkeys[0].int = "0xA"',
+ added = [Entry(sub_id='0x10000000-0x1FFFFFFF (sub-key 0x0000000A)')],
+ removed = [Entry(sub_id='0x10000000-0x1FFFFFFF (sub-key 0x00000001)')])
+
+ def test_key_type_changed(self):
+ # Change a bitmask key into a simple key
+ self.assert_comparison_result_after_change_equals(
+ "repo.keys[1] = CrmlSimpleKey(ref='Foo.Bar', name='Foo', int='0x2')",
+ modified = [Entry(sub_id = '0x00000002',
+ value_id = 'key_type',
+ source_value = 'bitmask_key',
+ target_value = 'simple_key'),
+ Entry(sub_id = '0x00000002',
+ value_id = 'name',
+ source_value = None,
+ target_value = 'Foo')])
+
+ # Change a simple key into a bitmask key
+ self.assert_comparison_result_after_change_equals(
+ "repo.keys[0] = CrmlBitmaskKey(int='0x1', name='Foo', bits=[CrmlBit(ref='Foo.Bit1', index=1)])",
+ modified = [Entry(sub_id = '0x00000001',
+ value_id = 'key_type',
+ source_value = 'simple_key',
+ target_value = 'bitmask_key'),
+ Entry(sub_id = '0x00000001',
+ value_id = 'name',
+ source_value = None,
+ target_value = 'Foo')])
+
+ def test_repository_attrs_changed(self):
+ def check(attrname, value_id, old_value, new_value):
+ self.assert_comparison_result_after_change_equals(
+ 'repo.%s = %r' % (attrname, new_value),
+ modified=[Entry(sub_id = None,
+ value_id = value_id,
+ source_value = old_value,
+ target_value = new_value)],
+ check_keys_in_entry_data=False)
+
+ check('uid_name', 'uid_name', 'KCrUidTest', 'Foobar')
+ check('owner', 'owner', '0x11223344', '0xAABBCCDD')
+ check('backup', 'backup', True, False)
+ check('rfs', 'rfs', True, False)
+ check('access.cap_rd', 'cap_rd', None, 'FooCapability')
+ check('access.cap_wr', 'cap_wr', None, 'FooCapability')
+ check('access.sid_rd', 'sid_rd', None, '0x12345678')
+ check('access.sid_wr', 'sid_wr', None, '0x12345678')
+
+ def test_repository_file_changed(self):
+ self.assert_comparison_result_after_change_equals(
+ '', # Make no modifications in the repository
+ modified=[Entry(sub_id = None,
+ value_id = 'file',
+ source_value = 'test.crml',
+ target_value = 'xyz.crml')],
+ target_resource_ref = 'xyz.crml',
+ check_keys_in_entry_data = False)
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_impl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_impl.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,265 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from cone.public import exceptions, plugin, api, container
+from cone.public.plugin import FlatComparisonResultEntry, DuplicateImplementationEntry
+from CRMLPlugin import crml_impl, crml_reader
+
+def impl_from_resource(resource_ref, configuration):
+ doc_root = plugin.ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
+ return crml_reader.CrmlReader.read_impl(resource_ref, configuration, doc_root)
+
+class MockGenerationContext(object):
+ def __init__(self):
+ self.tags = {}
+
+class TestCrmlImpl(unittest.TestCase):
+
+ def setUp(self):
+ project_dir = os.path.join(ROOT_PATH, 'gen_project')
+ self.project = api.Project(api.Storage.open(project_dir))
+ self.config = self.project.get_configuration('root.confml')
+
+ def test_has_ref(self):
+ impl = impl_from_resource('Layer1/implml/00000001_feature1.crml', self.config)
+ self.assertTrue(impl.has_ref(['Feature1.IntSetting']))
+ self.assertTrue(impl.has_ref(['Feature1.RealSetting']))
+ self.assertTrue(impl.has_ref(['Feature1.RealSetting', 'foo.bar']))
+
+ impl = impl_from_resource('Layer1/implml/00000003_bitmask_test.crml', self.config)
+ self.assertTrue(impl.has_ref(['BitmaskTest.Bit0']))
+ self.assertFalse(impl.has_ref(['BitmaskTest.FooBit']))
+
+ impl = impl_from_resource('Layer1/implml/0000000C_key_range.crml', self.config)
+ self.assertTrue(impl.has_ref(['KeyRangeTest.EmptySequenceSetting']))
+ self.assertTrue(impl.has_ref(['KeyRangeTest.EmptySequenceSetting.StringSubSetting']))
+ self.assertFalse(impl.has_ref(['KeyRangeTest']))
+ self.assertFalse(impl.has_ref(['KeyRangeTest.Foo']))
+
+ def test_list_output_files(self):
+ def oj( p2): # oj = output_join
+ return os.path.normpath(os.path.join('output', p2))
+
+ impl = impl_from_resource('Layer1/implml/00000001_feature1.crml', self.config)
+ self.assertEquals(impl.list_output_files(), [oj('00000001.txt')])
+
+ impl = impl_from_resource('Layer1/implml/00000003_bitmask_test.crml', self.config)
+ self.assertEquals(impl.list_output_files(), [oj('00000003.txt')])
+
+ gc = MockGenerationContext()
+ gc.tags['target'] = ['core']
+ impl.generation_context = gc
+ self.assertEquals(impl.list_output_files(), [oj('00000003.txt'), oj('private/100059C9/cenrep_rfs.txt')])
+
+ def test_is_cenrep_rfs_txt_to_be_generated(self):
+ impl = impl_from_resource('Layer1/implml/00000001_feature1.crml', self.config)
+ self.assertFalse(impl._is_cenrep_rfs_txt_to_be_generated())
+
+ gc = MockGenerationContext()
+ impl.generation_context = gc
+ self.assertFalse(impl._is_cenrep_rfs_txt_to_be_generated())
+ gc.tags['target'] = []
+ self.assertFalse(impl._is_cenrep_rfs_txt_to_be_generated())
+ gc.tags['target'] = ['uda']
+ self.assertFalse(impl._is_cenrep_rfs_txt_to_be_generated())
+ gc.tags['target'] = ['rofs3']
+ self.assertFalse(impl._is_cenrep_rfs_txt_to_be_generated())
+ gc.tags['target'] = ['rofs2']
+ self.assertTrue(impl._is_cenrep_rfs_txt_to_be_generated())
+ gc.tags['target'] = ['core']
+ self.assertTrue(impl._is_cenrep_rfs_txt_to_be_generated())
+ gc.tags['target'] = ['core', 'rofs3']
+ self.assertTrue(impl._is_cenrep_rfs_txt_to_be_generated())
+ gc.tags['target'] = ['uda', 'rofs2']
+ self.assertTrue(impl._is_cenrep_rfs_txt_to_be_generated())
+
+ def _open_config(self, project, config='root.confml'):
+ project_dir = os.path.join(ROOT_PATH, project)
+ project = api.Project(api.Storage.open(project_dir))
+ return project.get_configuration(config)
+
+ def test_compare(self):
+ conf1 = self._open_config('comp_project_1')
+ conf2 = self._open_config('comp_project_2')
+
+ crml_file = None
+ repo_uid = None
+
+ def entry(**kwargs):
+ kwargs['file'] = crml_file
+ kwargs['impl_type'] = 'crml'
+ kwargs['id'] = repo_uid
+ return plugin.FlatComparisonResultEntry(**kwargs)
+
+ comparison_result = None
+
+ crml_file = 'Layer1/implml/00000001_simple_keys.crml'
+ impl_filter = '00000001_simple_keys.crml$'
+ repo_uid = '0x00000001'
+ impls1 = plugin.get_impl_set(conf1, impl_filter)
+ impls2 = plugin.get_impl_set(conf2, impl_filter)
+ actual_result = impls1.flat_compare(impls2)
+
+ expected_mods = [
+ entry(sub_id='0x00000001', value_id='type', source_value='int', target_value='real'),
+ entry(sub_id='0x00000002', value_id='backup', source_value=True, target_value=False),
+
+ entry(sub_id='0x00000003', value_id='read_only', source_value=True, target_value=False),
+ entry(sub_id='0x00000004', value_id='read_only', source_value=False, target_value=True),
+ # Changing read-only changes also cap_wr
+ entry(sub_id='0x00000003', value_id='cap_wr', source_value='AlwaysFail', target_value=None),
+ entry(sub_id='0x00000004', value_id='cap_wr', source_value=None, target_value='AlwaysFail'),
+
+ entry(sub_id='0x00000005', value_id='type', source_value='int', target_value='real'),
+ entry(sub_id='0x00000006', value_id='name', source_value='Setting 6', target_value='Setting 6 (name changed)'),
+ entry(sub_id='0x00000007', value_id='ref', source_value='SimpleKeys.Setting7', target_value='SimpleKeys.Setting7RefChanged'),
+ entry(sub_id='0x00000008', value_id='cap_rd', source_value='ReadDeviceData', target_value='ReadUserData'),
+ entry(sub_id='0x00000008', value_id='cap_wr', source_value='WriteDeviceData', target_value='WriteUserData'),
+ entry(sub_id='0x00000008', value_id='sid_rd', source_value='0xAABBCCDD', target_value='0x11223344'),
+ entry(sub_id='0x00000008', value_id='sid_wr', source_value='0xDDCCBBAA', target_value='0x44332211'),
+ entry(sub_id='0x00000009', value_id='cap_rd', source_value='ReadDeviceData', target_value=None),
+ entry(sub_id='0x00000009', value_id='cap_wr', source_value='WriteDeviceData', target_value=None),
+ entry(sub_id='0x00000009', value_id='sid_rd', source_value='0xAABBCCDD', target_value=None),
+ entry(sub_id='0x00000009', value_id='sid_wr', source_value='0xDDCCBBAA', target_value=None),
+ ]
+ expected_removed = [
+ entry(sub_id='0x10000001'),
+ entry(sub_id='0x10000002'),
+ ]
+ expected_added = [
+ entry(sub_id='0x20000001'),
+ entry(sub_id='0x20000002'),
+ ]
+ expected_result = plugin.FlatComparisonResult(modified=expected_mods,
+ only_in_source=expected_removed,
+ only_in_target=expected_added)
+ self.assertEquals(actual_result, expected_result)
+
+
+ def test_compare_all(self):
+ conf1 = self._open_config('comp_project_1')
+ conf2 = self._open_config('comp_project_2')
+ impls1 = plugin.get_impl_set(conf1)
+ impls2 = plugin.get_impl_set(conf2)
+ actual_result = impls1.flat_compare(impls2)
+
+ expected_result = plugin.FlatComparisonResult(
+ only_in_source = [
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x10000001'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x10000002'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001 (bit 4)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000003 (bit 4)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x10000001'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF (sub-key 0x00000004)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF (sub-key 0x00000004)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x10001001-0x10001FFF'),
+ FlatComparisonResultEntry(file='Layer1/implml/10000001_removed_repo.crml', impl_type='crml', id='0x10000001'),
+ ],
+ only_in_target = [
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x20000001'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x20000002'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001 (bit 5)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000003 (bit 5)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x20000001'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF (sub-key 0x00000005)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF (sub-key 0x00000005)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x20001001-0x20001FFF'),
+ FlatComparisonResultEntry(file='Layer1/implml/20000001_added_repo.crml', impl_type='crml', id='0x20000001'),
+ ],
+ modified = [
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000001', value_id='type', source_value='int', target_value='real'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000002', value_id='backup', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000003', value_id='cap_wr', source_value='AlwaysFail', target_value=None),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000003', value_id='read_only', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000004', value_id='cap_wr', source_value=None, target_value='AlwaysFail'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000004', value_id='read_only', source_value=False, target_value=True),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000005', value_id='type', source_value='int', target_value='real'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000006', value_id='name', source_value='Setting 6', target_value='Setting 6 (name changed)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000007', value_id='ref', source_value='SimpleKeys.Setting7', target_value='SimpleKeys.Setting7RefChanged'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000008', value_id='cap_rd', source_value='ReadDeviceData', target_value='ReadUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000008', value_id='cap_wr', source_value='WriteDeviceData', target_value='WriteUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000008', value_id='sid_rd', source_value='0xAABBCCDD', target_value='0x11223344'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000008', value_id='sid_wr', source_value='0xDDCCBBAA', target_value='0x44332211'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000009', value_id='cap_rd', source_value='ReadDeviceData', target_value=None),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000009', value_id='cap_wr', source_value='WriteDeviceData', target_value=None),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000009', value_id='sid_rd', source_value='0xAABBCCDD', target_value=None),
+ FlatComparisonResultEntry(file='Layer1/implml/00000001_simple_keys.crml', impl_type='crml', id='0x00000001', sub_id='0x00000009', value_id='sid_wr', source_value='0xDDCCBBAA', target_value=None),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001', value_id='cap_rd', source_value='ReadDeviceData', target_value='ReadUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001', value_id='cap_wr', source_value='WriteDeviceData', target_value='WriteUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001', value_id='name', source_value='Bitmask 1', target_value='Bitmask 1 (name changed)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001', value_id='sid_rd', source_value='0xAABBCCDD', target_value='0x11223344'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001', value_id='sid_wr', source_value='0xDDCCBBAA', target_value='0x44332211'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001', value_id='type', source_value='int', target_value='binary'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001 (bit 2)', value_id='ref', source_value='BitmaskKeys.Bit2', target_value='BitmaskKeys.Bit2RefChanged'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000001 (bit 3)', value_id='invert', source_value=False, target_value=True),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000003', value_id='name', source_value='Modified read-only bitmask', target_value='Modified read-only bitmask (name changed)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000003', value_id='type', source_value='int', target_value='binary'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000003 (bit 2)', value_id='ref', source_value='BitmaskKeys.Bit2', target_value='BitmaskKeys.Bit2RefChanged'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000002_bitmask_keys.crml', impl_type='crml', id='0x00000002', sub_id='0x00000003 (bit 3)', value_id='invert', source_value=False, target_value=True),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='backup', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='cap_rd', source_value='ReadDeviceData', target_value='ReadUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='cap_wr', source_value='WriteDeviceData', target_value='WriteUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='first_index', source_value=1L, target_value=2L),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='index_bits', source_value='0x00000FF0', target_value='0x00001FE0'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='name', source_value='Sequence 1', target_value='Sequence 1 (name changed)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='ref', source_value='KeyRanges.Seq1', target_value='KeyRanges.Seq1RefChanged'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='sid_rd', source_value='0x11223344', target_value='0xAABBCCDD'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF', value_id='sid_wr', source_value='0x44332211', target_value='0xDDCCBBAA'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF (sub-key 0x00000002)', value_id='name', source_value='Sub-setting 2', target_value='Sub-setting 2 (name changed)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF (sub-key 0x00000002)', value_id='ref', source_value='SubSetting2', target_value='SubSetting2RefChanged'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00001001-0x00001FFF (sub-key 0x00000002)', value_id='type', source_value='int', target_value='real'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00002000-0x00002FFF', value_id='backup', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00002000-0x00002FFF', value_id='read_only', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003000-0x00003FFF', value_id='read_only', source_value=False, target_value=True),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='cap_rd', source_value='ReadDeviceData', target_value='ReadUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='cap_wr', source_value='WriteDeviceData', target_value='WriteUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='first_index', source_value=1, target_value=2),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='index_bits', source_value='0x00000FF0', target_value='0x00001FE0'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='name', source_value='Read-only sequence', target_value='Read-only sequence (name changed)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='ref', source_value='KeyRanges.ReadOnlySeq', target_value='KeyRanges.ReadOnlySeqRefChanged'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='sid_rd', source_value='0x11223344', target_value='0xAABBCCDD'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF', value_id='sid_wr', source_value='0x44332211', target_value='0xDDCCBBAA'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF (sub-key 0x00000002)', value_id='name', source_value='Sub-setting 2', target_value='Sub-setting 2 (name changed)'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF (sub-key 0x00000002)', value_id='ref', source_value='SubSetting2', target_value='SubSetting2RefChanged'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000003_key_ranges.crml', impl_type='crml', id='0x00000003', sub_id='0x00003001-0x00003FFF (sub-key 0x00000002)', value_id='type', source_value='int', target_value='real'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000001', value_id='key_type', source_value='simple_key', target_value='bitmask_key'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000002', value_id='key_type', source_value='bitmask_key', target_value='simple_key'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='backup', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='cap_rd', source_value='ReadDeviceData', target_value='ReadUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='cap_wr', source_value='AlwaysFail', target_value='WriteUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='name', source_value='Bitmask key to simple key (other attrs changed also)', target_value='Bitmask key to simple key (other attrs changed also [xyz])'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='read_only', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='sid_rd', source_value='0xAABBCCDD', target_value='0x11223344'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='sid_wr', source_value=None, target_value='0x44332211'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000004_key_type_changed.crml', impl_type='crml', id='0x00000004', sub_id='0x00000003', value_id='type', source_value='int', target_value='binary'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000005_repo_attrs_changed.crml', impl_type='crml', id='0x00000005', sub_id=None, value_id='backup', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000005_repo_attrs_changed.crml', impl_type='crml', id='0x00000005', sub_id=None, value_id='cap_rd', source_value='ReadDeviceData', target_value='ReadUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000005_repo_attrs_changed.crml', impl_type='crml', id='0x00000005', sub_id=None, value_id='cap_wr', source_value='WriteDeviceData', target_value='WriteUserData'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000005_repo_attrs_changed.crml', impl_type='crml', id='0x00000005', sub_id=None, value_id='rfs', source_value=True, target_value=False),
+ FlatComparisonResultEntry(file='Layer1/implml/00000005_repo_attrs_changed.crml', impl_type='crml', id='0x00000005', sub_id=None, value_id='sid_rd', source_value='0x11223344', target_value='0xAABBCCDD'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000005_repo_attrs_changed.crml', impl_type='crml', id='0x00000005', sub_id=None, value_id='sid_wr', source_value='0x44332211', target_value='0xDDCCBBAA'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000005_repo_attrs_changed.crml', impl_type='crml', id='0x00000005', sub_id=None, value_id='uid_name', source_value='RepoAttrsChanged', target_value='RepoAttrsChangedXyz'),
+ FlatComparisonResultEntry(file='Layer1/implml/00000006_renamed_repo_xyz.crml', impl_type='crml', id='0x00000006', sub_id=None, value_id='file', source_value='Layer1/implml/00000006_renamed_repo.crml', target_value='Layer1/implml/00000006_renamed_repo_xyz.crml'),
+ ],
+ duplicate = [
+ DuplicateImplementationEntry(impl_type='crml', id='0x30000000', files_in_source=['Layer1/implml/30000000_duplicate_repo1_proj1.crml', 'Layer1/implml/30000000_duplicate_repo2_proj1.crml'], files_in_target=['Layer1/implml/30000000_duplicate_repo2_proj2.crml', 'Layer1/implml/30000000_duplicate_repo1_proj2.crml'])
+ ])
+ self.assertEquals(actual_result, expected_result)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_model.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_model.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,497 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import __init__
+
+from cone.public import api, exceptions
+from CRMLPlugin.crml_model import *
+
+class TestCrmlAccess(unittest.TestCase):
+ def test_create_access_object(self):
+ acc = CrmlAccess()
+ self.assertEquals(acc.cap_rd, None)
+ self.assertEquals(acc.cap_wr, None)
+ self.assertEquals(acc.sid_rd, None)
+ self.assertEquals(acc.sid_wr, None)
+
+ acc = CrmlAccess(cap_rd='AlwaysPass', cap_wr='WriteUserData', sid_rd='0x12345678', sid_wr='0x87654321')
+ self.assertEquals(acc.cap_rd, 'AlwaysPass')
+ self.assertEquals(acc.cap_wr, 'WriteUserData')
+ self.assertEquals(acc.sid_rd, '0x12345678')
+ self.assertEquals(acc.sid_wr, '0x87654321')
+
+ def test_clone_access_object(self):
+ acc1 = CrmlAccess(cap_rd='AlwaysPass', cap_wr='WriteUserData', sid_rd='0x12345678', sid_wr='0x87654321')
+ acc2 = acc1.copy()
+ self.assertFalse(acc1 is acc2)
+ self.assertTrue(acc1 == acc2)
+ self.assertFalse(acc1 != acc2)
+
+ def test_compare_access_objects(self):
+ acc1 = CrmlAccess(cap_rd='AlwaysPass', cap_wr='WriteUserData', sid_rd='0x12345678', sid_wr='0x87654321')
+ acc2 = acc1.copy()
+ self.assertTrue(acc1 == acc2)
+ self.assertFalse(acc1 != acc2)
+
+ def check(attrname, value):
+ acc2 = acc1.copy()
+ setattr(acc1, attrname, value)
+ self.assertFalse(acc1 == acc2)
+ self.assertTrue(acc1 != acc2)
+
+ # Check that changing each individual attribute makes the comparison fail
+ check('cap_rd', 'ReadDeviceData')
+ check('cap_wr', 'WriteDeviceData')
+ check('sid_rd', '0x11223344')
+ check('sid_wr', '0x44332211')
+
+ subkeys = [
+ CrmlKeyRangeSubKey(ref='Sub1', name='Sub-key 1', type='int', int='0x1'),
+ CrmlKeyRangeSubKey(ref='Sub2', name='Sub-key 2', type='real', int='0x2'),
+ CrmlKeyRangeSubKey(ref='Sub3', name='Sub-key 3', type='string', int='0x3'),
+ ]
+ self.keyrange = CrmlKeyRange(
+ first_int = '0x10000000',
+ last_int = '0x1FFFFFFF',
+ first_index = 2,
+ index_bits = 0x0ff0,
+ backup = True,
+ read_only = True,
+ access = CrmlAccess(cap_rd='ReadUserData'),
+ subkeys = subkeys)
+
+ def test_create_keyrange_object(self):
+ self.assertRaises(ValueError, CrmlKeyRange)
+ self.assertRaises(ValueError, CrmlKeyRange, first_int='0x10')
+ self.assertRaises(ValueError, CrmlKeyRange, last_int='0x1F')
+
+ keyrange = CrmlKeyRange(first_int='0x10', last_int='0x1F')
+
+class TestCrmlRepository(unittest.TestCase):
+
+ def setUp(self):
+ keys = [
+ CrmlSimpleKey(ref='Foo.Bar', int='0x1'),
+ CrmlBitmaskKey(int='0x2', bits=[CrmlBit(ref='Foo.Bit1', index=1),
+ CrmlBit(ref='Foo.Bit2', index=2),
+ CrmlBit(ref='Foo.Bit4', index=4, invert=True)]),
+ CrmlKeyRange(first_int='0x10000000', last_int='0x1FFFFFFF', ref="Foo.Seq",
+ subkeys=[CrmlKeyRangeSubKey(ref='Sub1', name='Sub-key 1', type='int', int='0x1'),
+ CrmlKeyRangeSubKey(ref='Sub2', name='Sub-key 2', type='real', int='0x2')]),
+ ]
+
+ self.repo = CrmlRepository(
+ uid_value = '0x10203040',
+ uid_name = 'KCrUidTest',
+ owner = '0x11223344',
+ backup = True,
+ rfs = True,
+ version = '2',
+ access = CrmlAccess(cap_rd='ReadUserData'),
+ keys = keys)
+
+ def test_create_repo_object(self):
+ repo = CrmlRepository()
+ self.assertEquals(repo.uid_value, None)
+ self.assertEquals(repo.uid_name, None)
+ self.assertEquals(repo.owner, None)
+ self.assertEquals(repo.backup, False)
+ self.assertEquals(repo.rfs, False)
+ self.assertEquals(repo.access, CrmlAccess())
+ self.assertEquals(repo.keys, [])
+
+
+ keys = [
+ CrmlSimpleKey(ref='Foo.Bar', int='0x1'),
+ CrmlBitmaskKey(int='0x2', bits=[CrmlBit(ref='Foo.Bit1', index=1),
+ CrmlBit(ref='Foo.Bit2', index=2),
+ CrmlBit(ref='Foo.Bit4', index=4, invert=True)]),
+ CrmlKeyRange(first_int='0x10000000', last_int='0x1FFFFFFF', ref="Foo.Seq",
+ subkeys=[CrmlKeyRangeSubKey(ref='Sub1', name='Sub-key 1', type='int', int='0x1'),
+ CrmlKeyRangeSubKey(ref='Sub2', name='Sub-key 2', type='real', int='0x2')]),
+ ]
+
+ repo = self.repo
+ self.assertEquals(repo.uid_value, '0x10203040')
+ self.assertEquals(repo.uid_name, 'KCrUidTest')
+ self.assertEquals(repo.owner, '0x11223344')
+ self.assertEquals(repo.backup, True)
+ self.assertEquals(repo.rfs, True)
+ self.assertEquals(repo.version, '2')
+ self.assertEquals(repo.access, CrmlAccess(cap_rd='ReadUserData'))
+ self.assertEquals(repo.keys, keys)
+
+ def test_clone_repo_object(self):
+ repo1 = self.repo
+ repo2 = repo1.copy()
+ self.assertFalse(repo1 is repo2)
+ self.assertTrue(repo1 == repo2)
+ self.assertFalse(repo1 != repo2)
+
+ # Assert that the keys have been deep-copied
+ self.assertFalse(repo1.keys is repo2.keys)
+ self.assertEquals(repo1.keys, repo2.keys)
+ for i in xrange(len(repo1.keys)):
+ self.assertFalse(repo1.keys[i] is repo2.keys[i])
+
+ def test_compare_repo_objects(self):
+ repo1 = CrmlRepository()
+ repo2 = repo1.copy()
+ self.assertTrue(repo1 == repo2)
+ self.assertFalse(repo1 != repo2)
+
+ def check(attrname, value):
+ repo1 = self.repo
+ repo2 = repo1.copy()
+ setattr(repo2, attrname, value)
+ self.assertFalse(repo1 == repo2)
+ self.assertTrue(repo1 != repo2)
+
+ # Check that changing each individual attribute makes the comparison fail
+ check('uid_value', '0xbaadf00d')
+ check('uid_name', 'KFooUid')
+ check('owner', '0xbeef')
+ check('backup', False)
+ check('rfs', False)
+ check('access', CrmlAccess(cap_wr='WriteUserData'))
+ check('keys', ['foo'])
+ check('version', '3')
+
+ def check2(mod_func):
+ repo1 = self.repo
+ repo2 = repo1.copy()
+ mod_func(repo2)
+ self.assertFalse(repo1 == repo2)
+ self.assertTrue(repo1 != repo2)
+
+ # Check that changing the keys makes the comparison fail
+ check2(lambda r: setattr(r.keys[0], 'name', 'foo'))
+ check2(lambda r: setattr(r.keys[1], 'type', 'binary'))
+ check2(lambda r: setattr(r.keys[2], 'index_bits', 0x00ffff00))
+
+ def test_get_repo_refs(self):
+ self.assertEquals([], CrmlRepository(uid_value='0x1').get_refs())
+
+ expected = ['Foo.Bar',
+ 'Foo.Bit1',
+ 'Foo.Bit2',
+ 'Foo.Bit4',
+ 'Foo.Seq',
+ 'Foo.Seq.Sub1',
+ 'Foo.Seq.Sub2']
+ self.assertEquals(sorted(expected), sorted(self.repo.get_refs()))
+
+
+class TestCrmlSimpleKey(unittest.TestCase):
+ def setUp(self):
+ self.key = CrmlSimpleKey(
+ ref = 'Foo.Bar',
+ name = 'Foobar',
+ int = '0x1020',
+ type = 'real',
+ backup = True,
+ read_only = True,
+ access = CrmlAccess(cap_rd='ReadUserData'))
+
+ def test_create_key_object(self):
+ # Not specifying ref or index should make the constructor fail
+ self.assertRaises(ValueError, CrmlSimpleKey)
+ self.assertRaises(ValueError, CrmlSimpleKey, ref='Foo.Bar')
+ self.assertRaises(ValueError, CrmlSimpleKey, int='0x1')
+
+ key = CrmlSimpleKey(ref='Foo.Bar', int='0x1')
+ self.assertEquals(key.ref, 'Foo.Bar')
+ self.assertEquals(key.name, None)
+ self.assertEquals(key.int, '0x1')
+ self.assertEquals(key.type, 'int')
+ self.assertEquals(key.backup, False)
+ self.assertEquals(key.read_only, False)
+ self.assertEquals(key.access, CrmlAccess())
+
+ key = self.key
+ self.assertEquals(key.ref, 'Foo.Bar')
+ self.assertEquals(key.name, 'Foobar')
+ self.assertEquals(key.int, '0x1020')
+ self.assertEquals(key.type, 'real')
+ self.assertEquals(key.backup, True)
+ self.assertEquals(key.read_only, True)
+ self.assertEquals(key.access, CrmlAccess(cap_rd='ReadUserData'))
+
+ def test_clone_key_object(self):
+ key1 = self.key
+ key2 = key1.copy()
+ self.assertFalse(key1 is key2)
+ self.assertTrue(key1 == key2)
+ self.assertFalse(key1 != key2)
+
+ def test_compare_key_objects(self):
+ def check(attrname, value):
+ key1 = self.key
+ key2 = key1.copy()
+ setattr(key2, attrname, value)
+ self.assertFalse(key1 == key2)
+ self.assertTrue(key1 != key2)
+
+ # Check that changing each individual attribute makes the comparison fail
+ check('ref', 'Foo.Bar.Baz')
+ check('name', 'Testing')
+ check('int', 'KFooUid')
+ check('type', 'selection')
+ check('backup', False)
+ check('read_only', False)
+ check('access', CrmlAccess(cap_wr='WriteUserData'))
+
+ def test_get_key_refs(self):
+ self.assertEquals(['Foo.Bar'], self.key.get_refs())
+
+class TestCrmlBit(unittest.TestCase):
+ def test_create_bit_object(self):
+ # Not specifying ref or index should make the constructor fail
+ self.assertRaises(ValueError, CrmlBit)
+ self.assertRaises(ValueError, CrmlBit, ref='Foo.Bar')
+ self.assertRaises(ValueError, CrmlBit, index='3')
+
+ bit = CrmlBit(ref='Foo.Bar', index=1)
+ self.assertEquals(bit.ref, 'Foo.Bar')
+ self.assertEquals(bit.index, 1)
+ self.assertEquals(bit.invert, False)
+
+ bit = CrmlBit(ref='Foo.Bar.Baz', index=2, invert=True)
+ self.assertEquals(bit.ref, 'Foo.Bar.Baz')
+ self.assertEquals(bit.index, 2)
+ self.assertEquals(bit.invert, True)
+
+ def test_clone_bit_object(self):
+ bit1 = CrmlBit(ref='Foo.Bar.Baz', index=2, invert=True)
+ bit2 = bit1.copy()
+ self.assertFalse(bit1 is bit2)
+ self.assertTrue(bit1 == bit2)
+ self.assertFalse(bit1 != bit2)
+
+ def test_compare_bit_objects(self):
+ bit1 = CrmlBit(ref='Foo.Bar.Baz', index=2, invert=True)
+
+ def check(attrname, value):
+ bit2 = bit1.copy()
+ setattr(bit1, attrname, value)
+ self.assertFalse(bit1 == bit2)
+ self.assertTrue(bit1 != bit2)
+
+ check('ref', 'Foo.Bar')
+ check('index', 5)
+ check('invert', False)
+
+class TestCrmlBitmaskKey(unittest.TestCase):
+ def setUp(self):
+ bits = [
+ CrmlBit(ref='Foo.Bit1', index=1),
+ CrmlBit(ref='Foo.Bit2', index=2),
+ CrmlBit(ref='Foo.Bit4', index=4, invert=True),
+ ]
+ self.bm = CrmlBitmaskKey(
+ int = '0x500',
+ type = 'int',
+ backup = True,
+ read_only = True,
+ access = CrmlAccess(cap_rd='ReadUserData'),
+ bits = bits)
+
+ def test_create_bitmask_object(self):
+ self.assertRaises(ValueError, CrmlBitmaskKey)
+
+ bm = CrmlBitmaskKey(int='0x2')
+ self.assertEquals(bm.int, '0x2')
+ self.assertEquals(bm.type, 'int')
+ self.assertEquals(bm.backup, False)
+ self.assertEquals(bm.read_only, False)
+ self.assertEquals(bm.access, CrmlAccess())
+ self.assertEquals(bm.bits, [])
+
+ bm = self.bm
+ self.assertEquals(bm.int, '0x500')
+ self.assertEquals(bm.type, 'int')
+ self.assertEquals(bm.backup, True)
+ self.assertEquals(bm.read_only, True)
+ self.assertEquals(bm.access, CrmlAccess(cap_rd='ReadUserData'))
+ self.assertEquals(bm.bits, [CrmlBit(ref='Foo.Bit1', index=1),
+ CrmlBit(ref='Foo.Bit2', index=2),
+ CrmlBit(ref='Foo.Bit4', index=4, invert=True)])
+
+ def test_clone_bitmask_object(self):
+ bm1 = self.bm
+ bm2 = bm1.copy()
+ self.assertFalse(bm1 is bm2)
+ self.assertTrue(bm1 == bm2)
+ self.assertFalse(bm1 != bm2)
+
+ # Assert that the bits have been deep-copied
+ self.assertFalse(bm1.bits is bm2.bits)
+ self.assertEquals(bm1.bits, bm2.bits)
+ for i in xrange(len(bm1.bits)):
+ self.assertFalse(bm1.bits[i] is bm2.bits[i])
+
+ def test_compare_bitmask_objects(self):
+ def check(attrname, value):
+ bm1 = self.bm
+ bm2 = bm1.copy()
+ setattr(bm2, attrname, value)
+ self.assertFalse(bm1 == bm2)
+ self.assertTrue(bm1 != bm2)
+
+ check('int', '0x600')
+ check('type', 'binary')
+ check('backup', False)
+ check('read_only', False)
+ check('access', CrmlAccess(cap_rd='ReadDeviceData'))
+ check('bits', [CrmlBit(ref='Foo.Bit7', index=7),
+ CrmlBit(ref='Foo.Bit9', index=9)])
+
+ def test_get_bitmask_refs(self):
+ self.assertEquals([], CrmlBitmaskKey(int='0x1').get_refs())
+
+ expected = ['Foo.Bit1',
+ 'Foo.Bit2',
+ 'Foo.Bit4',]
+ self.assertEquals(sorted(expected), sorted(self.bm.get_refs()))
+
+class TestCrmlKeyRangeSubKey(unittest.TestCase):
+
+ def setUp(self):
+ self.subkey = CrmlKeyRangeSubKey(ref='Foo.Bar', name='Foobar', type='int', int='0x1')
+
+ def test_create_subkey_object(self):
+ self.assertRaises(ValueError, CrmlKeyRangeSubKey)
+ self.assertRaises(ValueError, CrmlKeyRangeSubKey, ref='Foo.Bar')
+ self.assertRaises(ValueError, CrmlKeyRangeSubKey, type='int')
+ self.assertRaises(ValueError, CrmlKeyRangeSubKey, int='0x1')
+
+ subkey = self.subkey
+ self.assertEquals(subkey.ref, 'Foo.Bar')
+ self.assertEquals(subkey.name, 'Foobar')
+ self.assertEquals(subkey.type, 'int')
+ self.assertEquals(subkey.int, '0x1')
+
+ def test_clone_subkey_object(self):
+ subkey1 = self.subkey
+ subkey2 = subkey1.copy()
+ self.assertFalse(subkey1 is subkey2)
+ self.assertTrue(subkey1 == subkey2)
+ self.assertFalse(subkey1 != subkey2)
+
+ def test_compare_subkey_objects(self):
+ def check(attrname, value):
+ subkey1 = self.subkey
+ subkey2 = subkey1.copy()
+ setattr(subkey2, attrname, value)
+ self.assertFalse(subkey1 == subkey2)
+ self.assertTrue(subkey1 != subkey2)
+
+ check('ref', 'Foo.Bar.Baz')
+ check('name', 'Test')
+ check('int', '0x2')
+ check('type', 'binary')
+
+class TestCrmlKeyRange(unittest.TestCase):
+ def setUp(self):
+ subkeys = [
+ CrmlKeyRangeSubKey(ref='Sub1', name='Sub-key 1', type='int', int='0x1'),
+ CrmlKeyRangeSubKey(ref='Sub2', name='Sub-key 2', type='real', int='0x2'),
+ CrmlKeyRangeSubKey(ref='Sub3', name='Sub-key 3', type='string', int='0x3'),
+ ]
+ self.keyrange = CrmlKeyRange(
+ ref = 'Foo.Seq',
+ first_int = '0x10000000',
+ last_int = '0x1FFFFFFF',
+ first_index = 2,
+ index_bits = 0x0ff0,
+ backup = True,
+ read_only = True,
+ access = CrmlAccess(cap_rd='ReadUserData'),
+ subkeys = subkeys)
+
+ def test_create_keyrange_object(self):
+ self.assertRaises(ValueError, CrmlKeyRange)
+ self.assertRaises(ValueError, CrmlKeyRange, first_int='0x10')
+ self.assertRaises(ValueError, CrmlKeyRange, last_int='0x1F')
+
+ keyrange = CrmlKeyRange(first_int='0x10', last_int='0x1F')
+ self.assertEquals(keyrange.first_int, '0x10')
+ self.assertEquals(keyrange.last_int, '0x1F')
+ self.assertEquals(keyrange.first_index, 0)
+ self.assertEquals(keyrange.index_bits, None)
+ self.assertEquals(keyrange.backup, False)
+ self.assertEquals(keyrange.read_only, False)
+ self.assertEquals(keyrange.access, CrmlAccess())
+ self.assertEquals(keyrange.subkeys, [])
+
+ keyrange = self.keyrange
+ self.assertEquals(keyrange.first_int, '0x10000000')
+ self.assertEquals(keyrange.last_int, '0x1FFFFFFF')
+ self.assertEquals(keyrange.first_index, 2)
+ self.assertEquals(keyrange.index_bits, 0x0ff0)
+ self.assertEquals(keyrange.backup, True)
+ self.assertEquals(keyrange.read_only, True)
+ self.assertEquals(keyrange.access, CrmlAccess(cap_rd='ReadUserData'))
+ self.assertEquals(keyrange.subkeys, [
+ CrmlKeyRangeSubKey(ref='Sub1', name='Sub-key 1', type='int', int='0x1'),
+ CrmlKeyRangeSubKey(ref='Sub2', name='Sub-key 2', type='real', int='0x2'),
+ CrmlKeyRangeSubKey(ref='Sub3', name='Sub-key 3', type='string', int='0x3')])
+
+
+ def test_clone_keyrange_object(self):
+ keyrange1 = self.keyrange
+ keyrange2 = keyrange1.copy()
+ self.assertFalse(keyrange1 is keyrange2)
+ self.assertTrue(keyrange1 == keyrange2)
+ self.assertFalse(keyrange1 != keyrange2)
+
+ # Assert that the sub-keys have been deep-copied
+ self.assertFalse(keyrange1.subkeys is keyrange2.subkeys)
+ self.assertEquals(keyrange1.subkeys, keyrange2.subkeys)
+ for i in xrange(len(keyrange1.subkeys)):
+ self.assertFalse(keyrange1.subkeys[i] is keyrange2.subkeys[i])
+
+ def test_compare_keyrange_objects(self):
+ def check(attrname, value):
+ keyrange1 = self.keyrange
+ keyrange2 = keyrange1.copy()
+ setattr(keyrange2, attrname, value)
+ self.assertFalse(keyrange1 == keyrange2)
+ self.assertTrue(keyrange1 != keyrange2)
+
+ check('first_int', '0x20000000')
+ check('last_int', '0x2FFFFFFF')
+ check('first_index', 3)
+ check('index_bits', 0xf00)
+ check('backup', False)
+ check('read_only', False)
+ check('access', CrmlAccess(cap_rd='ReadDeviceData'))
+ check('subkeys', [
+ CrmlKeyRangeSubKey(ref='Sub0x100', name='Sub-key 0x100', type='string', int='0x100'),
+ CrmlKeyRangeSubKey(ref='Sub0x200', name='Sub-key 0x200', type='binary', int='0x200')])
+
+ def test_get_keyrange_refs(self):
+ self.assertEquals([], CrmlKeyRange(first_int='0x1', last_int='0x2').get_refs())
+
+ expected = ['Foo.Seq',
+ 'Foo.Seq.Sub1',
+ 'Foo.Seq.Sub2',
+ 'Foo.Seq.Sub3',]
+ self.assertEquals(sorted(expected), sorted(self.keyrange.get_refs()))
+
+if __name__ == "__main__":
+ unittest.main()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,201 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+from cone.public import exceptions, plugin, api, container
+
+from CRMLPlugin.crml_model import *
+from CRMLPlugin.crml_reader import CrmlReader
+
+class TestCrmlReader(unittest.TestCase):
+
+ NAMESPACE = CrmlReader.NAMESPACE
+
+ def setUp(self):
+ self.reader = CrmlReader()
+
+ def assert_read_access_equals(self, data, expected):
+ etree = ElementTree.fromstring(data)
+ access = self.reader.read_access(etree)
+ self.assertEquals(expected, access)
+
+ def test_read_access(self):
+ data = """ """
+ self.assert_read_access_equals(data, CrmlAccess())
+
+ data = """
+
+
+
+
+ """ % self.NAMESPACE
+ self.assert_read_access_equals(data,
+ CrmlAccess(cap_rd='AlwaysPass', cap_wr='WriteDeviceData', sid_rd='0x12345678', sid_wr='0x87654321'))
+
+ def test_read_duplicate_access(self):
+ data = """
+
+
+
+
+
+
+ """ % self.NAMESPACE
+ self.assert_read_access_equals(data,
+ CrmlAccess(cap_rd='ReadDeviceData', cap_wr='WriteDeviceData', sid_rd='0x12345678', sid_wr='0x87654321'))
+
+
+ def read_key_from_xml(self, data):
+ etree = ElementTree.fromstring(data)
+ return self.reader.read_key(etree)
+
+ def assert_read_key_equals(self, data, expected):
+ self.assertEquals(expected, self.read_key_from_xml(data))
+
+ def test_read_key(self):
+ data = """
+
+
+
+ """ % self.NAMESPACE
+ self.assert_read_key_equals(data,
+ CrmlSimpleKey(ref='Foo.Bar', name='Foobar setting', int='0x01020304', type='real', read_only=True, backup=True,
+ access=CrmlAccess(cap_rd='AlwaysPass', cap_wr='WriteDeviceData', sid_rd='0x12345678', sid_wr='0x87654321')))
+
+ def test_read_invalid_key(self):
+ # Required attribute 'ref' missing
+ data = ' ' % self.NAMESPACE
+ self.assertRaises(exceptions.ParseError, self.read_key_from_xml, data)
+
+ def assert_read_bitmask_key_equals(self, data, expected):
+ etree = ElementTree.fromstring(data)
+ key = self.reader.read_bitmask_key(etree)
+ self.assertEquals(expected, key)
+
+ def test_read_bitmask_key(self):
+ data = """
+
+
+ 1
+ 4
+ 6
+
+ """ % self.NAMESPACE
+
+ self.assert_read_bitmask_key_equals(data,
+ CrmlBitmaskKey(name = 'Bitmask',
+ type = 'binary',
+ int = '0x00000001',
+ read_only = True,
+ backup = True,
+ access = CrmlAccess(cap_rd='ReadDeviceData'),
+ bits = [CrmlBit(ref='BitmaskTest.Bit0', index=1),
+ CrmlBit(ref='BitmaskTest.Bit3', index=4),
+ CrmlBit(ref='BitmaskTest.Bit5', index=6, invert=True)]))
+
+ def assert_read_key_range_equals(self, data, expected):
+ etree = ElementTree.fromstring(data)
+ key = self.reader.read_key_range(etree)
+ self.assertEquals(expected, key)
+
+ def test_read_key_range(self):
+ data = """
+
+
+
+ """ % self.NAMESPACE
+ self.assert_read_key_range_equals(data,
+ CrmlKeyRange(first_int='0x00004000', last_int='0x00004FFF', read_only=True, backup=False,
+ access=CrmlAccess(cap_rd='TCB')))
+
+ data = """
+
+
+
+
+
+
+
+ """ % self.NAMESPACE
+ self.assert_read_key_range_equals(data,
+ CrmlKeyRange(first_int='0x1001', last_int='0x1fff', index_bits=0x0ff0,
+ count_int='0x1000', first_index=1,
+ ref='KeyRangeTest.SequenceSetting',
+ name='Sequence setting', backup=True, read_only=False,
+ access=CrmlAccess(cap_rd='AlwaysPass', cap_wr='WriteDeviceData'),
+ subkeys=[CrmlKeyRangeSubKey(ref='StringSubSetting', name='String', int='0x0001', type='string8'),
+ CrmlKeyRangeSubKey(ref='IntSubSetting', name='Int', int='0x0002', type='int'),
+ CrmlKeyRangeSubKey(ref='IntSubSetting2', name='Int2', int='0x0003', type='int')]))
+
+ def assert_read_repo_equals(self, data, expected):
+ etree = ElementTree.fromstring(data)
+ key = self.reader.read_repository(etree)
+ self.assertEquals(expected, key)
+
+ def test_read_empty_repository(self):
+ data = """
+
+
+ """ % self.NAMESPACE
+ self.assert_read_repo_equals(data,
+ CrmlRepository(uid_name = 'EmptyRepo',
+ uid_value = '0x000000E1',
+ owner = '0xABCDDCBA',
+ backup = True,
+ rfs = True,
+ version = '2'))
+
+ def test_read_simple_repository(self):
+ data = """
+
+
+
+
+
+ """ % self.NAMESPACE
+ self.assert_read_repo_equals(data,
+ CrmlRepository(
+ uid_name = 'SimpleRepo',
+ uid_value = '0x000000E2',
+ owner = '0xF00DBEEF',
+ backup = True,
+ rfs = True,
+ version = '1',
+ keys = [CrmlSimpleKey(ref='Foo.Key1', name='Fookey 1', int='0x00000001', type='int', read_only=True, backup=True, access=CrmlAccess(cap_wr='AlwaysFail')),
+ CrmlSimpleKey(ref='Foo.Key2', name='Fookey 2', int='0x00000002', type='real', read_only=False, backup=True),
+ CrmlSimpleKey(ref='Foo.Key3', name='Fookey 3', int='0x00000003', type='string', read_only=True, backup=False, access=CrmlAccess(cap_wr='AlwaysFail')),]))
+
+
+if __name__ == "__main__":
+ unittest.main()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_writer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_writer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,171 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest, logging
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from cone.public import exceptions, plugin, api, container
+
+from CRMLPlugin.crml_model import *
+from CRMLPlugin.crml_writer import CrmlTxtWriter
+
+log = logging.getLogger('unittest_crml_writer')
+
+FEATURES = {
+# Ref Type Value (+ optionally orig. value)
+ 'Foo.Int' : ('int', 5, '5'),
+ 'Foo.Real' : ('real', 5.5, '5.5'),
+ 'Foo.String' : ('string', 'Test'),
+ 'Foo.UnicodeString' : ('string', u'100\u20ac'),
+ 'Foo.Bit1' : ('boolean', True, 'true'),
+ 'Foo.Bit2' : ('boolean', False, 'false'),
+ 'Foo.Bit3' : ('boolean', True, '1'),
+ 'Foo.Bit4' : ('boolean', False, '0'),
+ 'Foo.Bit5' : ('boolean', True, '1'),
+ 'Foo.Bit6' : ('boolean', False, '0'),
+ 'Foo.Seq.Int' : ('int', ['1', '2', '3']),
+ 'Foo.Seq.Real' : ('real', ['0.1', '0.2', '0.3']),
+ 'Foo.Seq.String' : ('string', ['Test1', 'Test2', 'Test3']),
+}
+
+class Mock(object):
+ pass
+
+class MockFeature(object):
+ def __init__(self, ref):
+ self.ref = ref
+ def get_value(self):
+ return FEATURES[self.ref][1]
+ def get_original_value(self):
+ val = FEATURES[self.ref]
+ if len(val) == 3: return val[2]
+ else: return val[1]
+ def get_type(self):
+ return FEATURES[self.ref][0]
+
+class MockConfiguration(object):
+ def get_default_view(self):
+ dview = Mock()
+ dview.get_feature = lambda ref: MockFeature(ref)
+ return dview
+
+class TestCrmlTxtWriter(unittest.TestCase):
+ def setUp(self):
+ self.writer = CrmlTxtWriter(MockConfiguration(), log)
+
+ def test_write_access(self):
+ def check(acc, expected):
+ actual = self.writer.get_access_line(acc)
+ self.assertEquals(expected, actual)
+
+ check(CrmlAccess(), '')
+ check(CrmlAccess(cap_rd="AlwaysPass"), 'cap_rd=alwayspass')
+ check(CrmlAccess(cap_wr="AlwaysPass"), 'cap_wr=alwayspass')
+ check(CrmlAccess(cap_rd="ReadDeviceData", cap_wr="WriteDeviceData"),
+ 'cap_rd=ReadDeviceData cap_wr=WriteDeviceData')
+ check(CrmlAccess(sid_rd="0x12345678", sid_wr="0x87654321"),
+ 'sid_rd=0x12345678 sid_wr=0x87654321')
+ check(CrmlAccess(cap_rd="ReadDeviceData", cap_wr="WriteDeviceData", sid_rd="0x12345678", sid_wr="0x87654321"),
+ 'sid_rd=0x12345678 cap_rd=ReadDeviceData sid_wr=0x87654321 cap_wr=WriteDeviceData')
+
+ def test_write_simple_key(self):
+ def check(key, expected):
+ key_line = self.writer.get_cenrep_entries(key)[0]
+ actual = self.writer.get_cenrep_entry_line(key_line)
+ self.assertEquals(expected, actual)
+
+ check(CrmlSimpleKey(ref='Foo.Int', int='0x01020304'),
+ '0x1020304 int 5 0')
+ check(CrmlSimpleKey(ref='Foo.Int', int='0x01020304', backup=True),
+ '0x1020304 int 5 16777216')
+ check(CrmlSimpleKey(ref='Foo.Int', int='0x01020304', backup=True, access=CrmlAccess(cap_rd='AlwaysPass', cap_wr='AlwaysFail')),
+ '0x1020304 int 5 16777216 cap_rd=alwayspass cap_wr=alwaysfail')
+
+
+class TestKeyRange(unittest.TestCase):
+
+ def test_get_shift_count_with_small_range(self):
+ self.assertEquals(CrmlTxtWriter.get_range_shift(0xff00), 8)
+
+ def test_get_shift_count_with_medium_range(self):
+ self.assertEquals(CrmlTxtWriter.get_range_shift(0xff000), 12)
+
+ def test_get_shift_count_with_larger_range(self):
+ self.assertEquals(CrmlTxtWriter.get_range_shift(0xff0000), 16)
+
+ def test_get_shift_count_with_split_range(self):
+ self.assertEquals(CrmlTxtWriter.get_range_shift(0xfc00), 10)
+
+ def test_get_range_with_larger_range(self):
+ self.assertEquals(CrmlTxtWriter.get_range(0xff0000), 0xffff)
+ self.assertEquals(CrmlTxtWriter.get_range(0xff000), 0xfff)
+ self.assertEquals(CrmlTxtWriter.get_range(0xff00), 0xff)
+ self.assertEquals(CrmlTxtWriter.get_range(0xfc0000), 0x3ffff)
+
+ def test_get_index_with_whole_range_00(self):
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,0,0), 0x20000)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,0,1), 0x20001)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,0,2), 0x20002)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,0,3), 0x20003)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,0,4), 0x20004)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,0,5), 0x20005)
+
+ def test_get_index_with_whole_range_10(self):
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,1,0), 0x30000)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,1,1), 0x30001)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,1,2), 0x30002)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,1,3), 0x30003)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,1,4), 0x30004)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,1,5), 0x30005)
+
+ def test_get_index_with_whole_range_f(self):
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,16,0), 0x120000)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,16,1), 0x120001)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,16,2), 0x120002)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,16,3), 0x120003)
+ self.assertEquals(CrmlTxtWriter.get_index(0x0,2, 0xff0000,16,4), 0x120004)
+
+ def test_get_seqid_with_whole_range_00(self):
+ self.assertEquals(CrmlTxtWriter.get_seqid(0x0,2, 0xff0000,0x20000), 0)
+ self.assertEquals(CrmlTxtWriter.get_seqid(0x0,2, 0xff0000,0x20004), 0)
+ self.assertEquals(CrmlTxtWriter.get_seqid(0x0,2, 0xff0000,0x30001), 1)
+ self.assertEquals(CrmlTxtWriter.get_seqid(0x0,2, 0xff0000,0x120000), 16)
+
+ def test_get_subseqid(self):
+ self.assertEquals(CrmlTxtWriter.get_subseqid(0x0,0, 0xff0000,0x4), 4)
+ self.assertEquals(CrmlTxtWriter.get_subseqid(0x0,2, 0xff0000,0x120004), 4)
+ self.assertEquals(CrmlTxtWriter.get_subseqid(0x0,2, 0xff0000,0x120012), 18)
+ self.assertEquals(CrmlTxtWriter.get_subseqid(0xcf000002,2, 0xff0000,0xcf000002), 0)
+ self.assertEquals(CrmlTxtWriter.get_subseqid(0xcf000002,2, 0xff0000,0xcf000006), 4)
+ self.assertEquals(CrmlTxtWriter.get_subseqid(0xcf000002,2, 0xff0000,0xcf00000f), 13)
+ self.assertEquals(CrmlTxtWriter.get_subseqid(0xcf000002,2, 0xff0000,0xcf020002), 0)
+
+ def test_get_index_with_example_range_f(self):
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,0,0), 0xcf020002)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,0,1), 0xcf020003)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,0,2), 0xcf020004)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,0,3), 0xcf020005)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,0,4), 0xcf020006)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,0,5), 0xcf020007)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,1,0), 0xcf030002)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,1,3), 0xcf030005)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,1,5), 0xcf030007)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,16,0), 0xcf120002)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,16,3), 0xcf120005)
+ self.assertEquals(CrmlTxtWriter.get_index(0xcf000002,2, 0xff0000,16,5), 0xcf120007)
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_txt_generation.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_txt_generation.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,87 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import exceptions, plugin, api, container
+
+from CRMLPlugin import crml_impl
+
+def abspath(path):
+ return os.path.normpath(os.path.join(ROOT_PATH, path))
+
+class TestCrmlImpl(BaseTestCase):
+
+ def test_generate_from_project_with_rfs(self):
+ project_dir = abspath('gen_project')
+ config = 'root.confml'
+ output_dir = abspath('temp/gen_output1')
+ expected_dir = abspath('gen_expected')
+
+ self.remove_if_exists(output_dir)
+
+ prj = api.Project(api.Storage.open(project_dir))
+ config = prj.get_configuration(config)
+ impls = plugin.get_impl_set(config, 'crml$')
+ impls.output = output_dir
+ impls.generation_context.tags['target'] = ['rofs2']
+ impls.generate()
+ impls.post_generate()
+
+ self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'])
+
+ def test_generate_from_project_without_rfs(self):
+ project_dir = abspath('gen_project')
+ config = 'root.confml'
+ output_dir = abspath('temp/gen_output2')
+ expected_dir = abspath('gen_expected')
+
+ self.remove_if_exists(output_dir)
+
+ prj = api.Project(api.Storage.open(project_dir))
+ config = prj.get_configuration(config)
+ impls = plugin.get_impl_set(config, 'crml$')
+ impls.output = output_dir
+ impls.generation_context.tags['target'] = []
+ impls.generate()
+ impls.post_generate()
+
+ self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn', 'private'])
+ self.assertFalse(os.path.exists(os.path.join(output_dir, 'private/100059C9/cenrep_rfs.txt')))
+
+
+ def test_generate_from_project_duplicate_rfs(self):
+ project_dir = abspath('duplicate_rfs_project')
+ config = 'root.confml'
+ output_dir = abspath('temp/duplicate_rfs_output')
+ expected_dir = abspath('duplicate_rfs_expected')
+
+ self.remove_if_exists(output_dir)
+
+ prj = api.Project(api.Storage.open(project_dir))
+ config = prj.get_configuration(config)
+ impls = plugin.get_impl_set(config, 'crml$')
+ impls.output = output_dir
+ impls.generation_context.tags['target'] = ['rofs2']
+ impls.generate()
+ impls.post_generate()
+
+ self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'])
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeCRMLPlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from CRMLPlugin import __version__
+
+setup(
+ name = "conecrmlplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "crmlplugin.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine Configuration Tool CRML plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware", # project home page, if any
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['crml = CRMLPlugin.crml_reader:CrmlReader']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
+
+__all__ = ['confflattener', 'genconfmlplugin', 'xslttransformer']
+
+import pkg_resources
+import sys,os
+
+
+try:
+ pkg_resources.require("Cone")
+except pkg_resources.DistributionNotFound:
+ ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+ sys.path.append(ROOT_PATH)
+ sys.path.append(os.path.join(ROOT_PATH,'..'))
+ sys.path.append(os.path.join(ROOT_PATH,'../..'))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/confflattener.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/confflattener.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+Configuration flattener
+'''
+
+import re
+import os
+import sys
+import logging
+import xml.parsers.expat
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+import copy
+
+
+
+class ConfigurationFlattener():
+ """
+ Configuration flattener
+ """
+
+ def _init(self):
+ self.logger = logging.getLogger('cone.gcfml(%s)' % self.ref)
+ pass
+
+
+ def flat(self, conf_from_org, settings, to_config):
+ """
+ Flats configuration to one element xml element
+ """
+ """
+ Get the default view
+ Create the new flat configuration
+ """
+ dview_from = conf_from_org.get_default_view()
+
+ """ Go through the required settings """
+ for setting in settings:
+ setting_name = setting.replace('/', '.')
+ try:
+ for fea in dview_from.get_features(setting_name):
+ """ Add the given feature ref and its children """
+ newfea = copy.copy(fea._obj)
+ to_config.add_feature(newfea, fea.namespace)
+ for subfeaname in fea.list_features():
+ subfea = fea.get_feature(subfeaname)
+ newfea = copy.copy(subfea._obj)
+ to_config.add_feature(newfea, subfea.namespace)
+ except exceptions.NotFound, e:
+ logging.getLogger('cone.gcfml').warning('Failed to get feature: %s , %s %s' % (setting_name, type(e), e) )
+ except Exception, e:
+ logging.getLogger('cone.gcfml').warning('Failed to flat feature: %s , %s %s' % (setting_name, type(e), e) )
+
+ """ Copy all data values from the existing configuration to the new configuration """
+ toview = to_config.get_default_view()
+ for fea in toview.get_features('**'):
+ fromfea = dview_from.get_feature(fea.fqr)
+ if fromfea.get_value() != None:
+ fea.set_value(fromfea.get_value())
+ return to_config
+
+ def create_configuration(self, conf_from_org, settings, path="tempfile.confml"):
+ """
+ Flats configuration to one feature and data confml
+ """
+ """
+ Get the default view
+ Create the new flat configuration
+ """
+ prj = conf_from_org.get_project()
+ flat = prj.create_configuration(path)
+ (root,ext) = os.path.splitext(path)
+ dataname = "%s_data%s" % (root,ext)
+ flat.create_configuration(dataname)
+ self.flat(conf_from_org, settings, flat)
+ flat.close()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,401 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+GenConfml plugin for ConE
+'''
+
+import re
+import os
+import sys
+import logging
+import xml.parsers.expat
+import confflattener
+import xslttransformer
+import codecs
+import tempfile
+import tempfile
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+from cone.confml import persistentconfml
+
+class GenconfmlImpl(plugin.ImplBase):
+ """
+ GenConfml plugin implementation
+ """
+
+ IMPL_TYPE_ID = "gcfml"
+
+
+ def __init__(self,ref,configuration, output='output', linesep=os.linesep, reader=None):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.logger = logging.getLogger('cone.gcfml(%s)' % self.ref)
+ self.errors = False
+ self.xstl_etree = None
+ self.xslt_temp_file_name = os.path.join(tempfile.gettempdir(), "genconfml_temp_%i.xslt" % os.getpid())
+ self.set_output_root(output)
+ self.linesep = linesep
+ self._flatconfig = None
+ self.temp_confml_file = os.path.join(tempfile.gettempdir(),'temp_flatted_%i.confml' % os.getpid())
+ self.reader = reader
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ """
+ self.create_output()
+ return
+
+ def get_refs(self):
+ result = []
+ for ref in self.reader.settings:
+ # Process the reference, so that it will work with has_ref().
+ # E.g. 'MyFeature/MySetting' -> 'MyFeature.MySetting'
+ # 'MyFeature/* -> 'MyFeature'
+ ref = ref.replace('/', '.')
+ if ref.endswith('.*'):
+ ref = ref[:-2]
+ result.append(ref)
+ return result
+
+ def list_output_files(self):
+ """ Return a list of output files as an array. """
+ return [self.get_output_filename()]
+
+ def get_output_filename(self):
+ """ Return a output file name. """
+
+ name = self.reader.name
+ if name == None: name = ""
+ target = self.reader.target
+ if target == None: target = ""
+ output = self.output
+ if self.output == None: output = ""
+
+ # Make sure that target file is generated under output
+ target = utils.resourceref.remove_begin_slash(utils.resourceref.norm(target))
+ subdir = self.reader.subdir
+ if subdir == None:
+ self.output_subdir = subdir
+ output_file = os.path.normpath(os.path.join(output, target, name))
+
+ return output_file
+
+ def create_output(self, layers=None):
+ """ Generate all output """
+ resource = self.configuration.get_resource(self.ref)
+ write_element_enc(self.reader.stylesheet_elem, self.xslt_temp_file_name, self.reader.stylesheet_output_enc)
+ gen = Generator()
+
+ target = self.reader.target
+ if target == None: target = ""
+
+ output_file = self.get_output_filename()
+ # Don't create the dirs here, since the output file may be filtered out
+ # if it is empty
+ #if not os.path.exists(os.path.dirname(output_file)):
+ # os.makedirs(os.path.dirname(output_file))
+
+ self.logger.info('Generating %s' % output_file)
+
+ flatted_conf_as_element = persistentconfml.ConfmlWriter().dumps(self.flatconfig)
+ postprocessed_element = self.post_process_flattening(flatted_conf_as_element)
+ write_element_enc(postprocessed_element, self.temp_confml_file, self.reader.stylesheet_output_enc)
+ gen.generate(self.configuration, resource, output_file, self.xslt_temp_file_name, self.reader.settings, self.reader.stylesheet_output_enc)
+
+ def post_process_flattening(self, element):
+ """
+ Pick just data element and build document out of it
+ """
+
+ data_element = element.find("data")
+ if data_element == None:
+ self.logger.warning('No data to generate!!')
+ new_doc = "" + " "
+ else:
+ new_doc = "" + ElementTree.tostring(data_element) + " "
+ return ElementTree.fromstring(new_doc)
+
+ @property
+ def flatconfig(self):
+ """
+ Create a flat configuration from the current configuration with the given setting refs.
+ Take the last configuration element, which will contain the data elements
+ """
+ if not self._flatconfig:
+ try:
+ cf = confflattener.ConfigurationFlattener()
+ self._flatconfig = api.Configuration()
+ cf.flat(self.configuration, self.reader.settings, self._flatconfig)
+ except (exceptions.ConeException, TypeError, Exception), e:
+ utils.log_exception(self.logger, 'Failed to flat configuration with settings %s. Exception: %s' % (self.reader.settings, e))
+ raise exceptions.ConeException('Failed to flat configuration. Exception: %s' % e)
+ return self._flatconfig
+
+
+def write_element(element, output, linesep=os.linesep):
+ """
+ """
+ if element != None and ElementTree.iselement(element):
+ enc = None
+
+
+ try:
+ out_file = open(output, 'w')
+ out_string = ElementTree.tostring(element)
+ out_string = out_string.replace('\r\n', linesep)
+ out_string = out_string.replace('\n', linesep)
+ out_file.write(out_string)
+ out_file.close()
+ except Exception, e:
+ raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))
+ else:
+ raise exceptions.ConeException('Cannot write element to file, because None element passed or not Element passed.')
+
+def remove_namespace(doc, namespace):
+ """Remove namespace in the passed document in place."""
+ ns = u'{%s}' % namespace
+ nsl = len(ns)
+ for elem in doc.getiterator():
+ if elem.tag.startswith(ns):
+ elem.tag = elem.tag[nsl:]
+
+def write_element_enc(element, output, enc, linesep=os.linesep):
+ """
+ Writes element to file
+ """
+ if element != None and ElementTree.iselement(element):
+ enc = None
+
+
+ try:
+ remove_namespace(element, 'http://www.s60.com/xml/genconfml/1')
+
+
+ out_file = codecs.open(output, 'w', enc)
+ output_string = ElementTree.tostring(element)
+ output_string = output_string.replace('\r\n', linesep)
+ output_string = output_string.replace('\n', linesep)
+ out_file.write(output_string)
+ out_file.close()
+ except Exception, e:
+ raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))
+ else:
+ raise exceptions.ConeException('Cannot write element to file, because None element passed or not Element passed.')
+
+
+def write_element_tempfile(element, tempfile):
+ """
+ Writes element to temp file
+ """
+ if element != None and ElementTree.iselement(element):
+
+ try:
+ tempfile.write(ElementTree.tostring(element))
+ except Exception, e:
+ raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))
+ else:
+ raise exceptions.ConeException('Cannot write element to file, because None element passed or not Element passed.')
+
+class GenconfmlImplReader(plugin.ReaderBase):
+ """
+ Parses a single gcfml file
+ """
+ NAMESPACE = 'http://www.s60.com/xml/genconfml/1'
+ IGNORED_NAMESPACES = ['http://www.w3.org/1999/XSL/Transform',
+ 'http://www.w3.org/2001/xinclude']
+ FILE_EXTENSIONS = ['gcfml']
+
+ def __init__(self):
+ self.stylesheet = None
+ self.namespaces = self.IGNORED_NAMESPACES + [self.NAMESPACE]
+ self.settings = None
+ self.name = None
+ self.subdir = None
+ self.target = None
+ self.stylesheet_elem = None
+ self.stylesheet_output_enc = None
+ self.nss = None
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+
+ reader = GenconfmlImplReader()
+ reader.from_etree(etree)
+ return GenconfmlImpl(resource_ref, configuration, reader=reader)
+
+ def from_etree(self, etree):
+ self.stylesheet = self.parse_stylesheet(etree)
+ self.settings = self.parse_settings(etree)
+ self.name = self.parse_name(etree)
+ self.subdir = self.parse_subdir(etree)
+ self.target = self.parse_target(etree)
+ self.stylesheet_elem = self.parse_stylesheet_elem(etree)
+ self.stylesheet_output_enc = self.parse_stylesheet_output_enc(etree)
+ self.nss = self.parse_stylesheet_nss(etree)
+
+ return
+
+ def parse_target(self, etree):
+ """
+ Parses target from etree
+ """
+
+ target = ""
+ for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
+ if elem != None:
+ target = elem.get('target')
+
+ return target
+
+ def parse_name(self, etree):
+ """
+ Parses name from etree
+ """
+
+ name = ""
+ for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
+ if elem != None:
+ name = elem.get('name')
+
+ return name
+
+ def parse_subdir(self, etree):
+ """
+ Parses subdir from etree
+ """
+
+ subdir = ""
+ for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
+ if elem != None:
+ subdir = elem.get('subdir')
+ if subdir == None:
+ subdir = ""
+
+ return subdir
+
+
+ def parse_stylesheet(self,etree):
+ """
+ Parses stylesheet from getree
+ """
+
+ stylesheet = ""
+ stylesheet_elem = etree.find("{%s}stylesheet" % self.namespaces[0])
+ if stylesheet_elem != None:
+ stylesheet = ElementTree.tostring(stylesheet_elem)
+ return stylesheet
+
+ def parse_stylesheet_output_enc(self, etree):
+ enc = ""
+ ss_elem = etree.find("{%s}stylesheet" % self.namespaces[0])
+ if ss_elem != None:
+ children = ss_elem.getchildren()
+ for child in children:
+ if child.tag == '{%s}output' % self.namespaces[0]:
+ enc = child.attrib.get('encoding')
+ return enc
+
+ def parse_stylesheet_nss(self, etree):
+ nss = None
+
+ for elem in etree.getiterator():
+ name = elem.tag
+ if name[0] == "{":
+ uri, tag = name[1:].split("}")
+ if tag == "stylesheet":
+ nss = uri
+ return nss
+
+ def parse_stylesheet_elem(self,etree):
+ """
+ Parses stylesheet element from getree
+ """
+
+ return etree.find("{%s}stylesheet" % self.namespaces[0])
+
+ def parse_settings(self,etree):
+ """
+ Parses settings from etree
+ """
+
+ settings = []
+
+ for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
+ if elem != None:
+ setting_elems = elem.findall("{%s}setting" % self.namespaces[2])
+ for setting_elem in setting_elems:
+ if setting_elem != None:
+ settings.append(setting_elem.get('ref'))
+
+ return settings
+
+class Generator(object):
+ """
+ Genconfml generator
+ """
+ def __init__(self):
+ self.temp_confml_file = os.path.join(tempfile.gettempdir(),'temp_flatted_%i.confml' % os.getpid())
+ pass
+
+ def post_process_flattening(self, element):
+ """
+ Pick just data element and build document out of it
+ """
+
+ data_element = element.find("data")
+ if data_element == None:
+ self.logger.warning('No data to generate!!')
+ new_doc = "" + " "
+ else:
+ new_doc = "" + ElementTree.tostring(data_element) + " "
+ return ElementTree.fromstring(new_doc)
+
+
+ def generate(self, configuration, input, output, xslt, settings, enc=sys.getdefaultencoding()):
+ """
+ Generates output
+ """
+ self.logger = logging.getLogger('cone.gcfml{%s}' % input.path)
+
+
+ try:
+ tf = xslttransformer.XsltTransformer()
+ tf.transform_lxml(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), output, enc)
+ #tf.transform_4s(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), output, enc)
+ except (exceptions.ConeException, TypeError, Exception), e:
+ logging.getLogger('cone.gcfml').warning('Failed to do XSLT tranformation. Exception: %s' % e)
+ raise exceptions.ConeException('Failed to do XSLT tranformation. Exception: %s' % e)
+
+ """ Removes template files """
+ if not logging.getLogger('cone').getEffectiveLevel() != 10:
+ os.remove(os.path.abspath(self.temp_confml_file))
+ os.remove(os.path.abspath(xslt))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/b/feature1_file_5.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/b/feature1_file_5.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/b/x/y/feature1_file_7.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/b/x/y/feature1_file_7.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/feature1_file_4.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/feature1_file_4.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/x/feature1_file_6.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/a/x/feature1_file_6.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/feature1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/feature1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+10
+default string
+3.14
+1
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/feature1_file_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/feature1_file_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/feature2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/feature2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+default 1
+default 2
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/special_char_test.txt
Binary file configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/special_char_test.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/x/feature1_file_2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/x/feature1_file_2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/x/y/feature1_file_3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/x/y/feature1_file_3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/b/feature1_file_5.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/b/feature1_file_5.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/b/x/y/feature1_file_7.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/b/x/y/feature1_file_7.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/feature1_file_4.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/feature1_file_4.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/x/feature1_file_6.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/a/x/feature1_file_6.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/feature1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/feature1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+200
+layer 2 string
+2.005
+2
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/feature1_file_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/feature1_file_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/feature2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/feature2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+default 1
+default 2
+layer2 (1)
+layer2 (2)
+layer2 (3)
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/special_char_test.txt
Binary file configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/special_char_test.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/x/feature1_file_2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/x/feature1_file_2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/x/y/feature1_file_3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/x/y/feature1_file_3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/b/feature1_file_5.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/b/feature1_file_5.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/b/x/y/feature1_file_7.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/b/x/y/feature1_file_7.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/feature1_file_4.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/feature1_file_4.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/x/feature1_file_6.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/a/x/feature1_file_6.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/feature1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/feature1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+300
+layer 3 string
+3.005
+3
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/feature1_file_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/feature1_file_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/feature2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/feature2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+layer3 (1)
+layer3 (2)
+default 1
+default 2
+layer2 (1)
+layer2 (2)
+layer2 (3)
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/special_char_test.txt
Binary file configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/special_char_test.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/x/feature1_file_2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/x/feature1_file_2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/x/y/feature1_file_3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/x/y/feature1_file_3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/b/feature1_file_5.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/b/feature1_file_5.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/b/x/y/feature1_file_7.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/b/x/y/feature1_file_7.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/feature1_file_4.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/feature1_file_4.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/x/feature1_file_6.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/a/x/feature1_file_6.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/feature1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/feature1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+400
+layer 4 string
+4.005
+4
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/feature1_file_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/feature1_file_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/feature2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/feature2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+layer4 (1)
+layer4 (2)
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/special_char_test.txt
Binary file configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/special_char_test.txt has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/x/feature1_file_2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/x/feature1_file_2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/x/y/feature1_file_3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/x/y/feature1_file_3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,111 @@
+
+
+
+ Feature with all setting types
+
+ A folder setting
+
+
+ A real setting
+
+
+ A file setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A folder sub-setting
+
+
+ A real sub-setting
+
+
+ A file sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ default_folder
+ 3.14
+ default_file.txt
+ 10
+ default string
+ true
+ 1
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ default_folder
+ 2.5
+ default_file.txt
+ 10
+ rfs string
+ true
+ 1
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/confml/feature2.confml
Binary file configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/confml/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/confml/special_char_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/confml/special_char_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ älämölö
+ ударениÑ
+ ελληνικά
+ カタカナ
+ ä¸åœ‹è©±
+ <&>
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_1.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_1.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_2.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_2.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_3.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_3.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_4.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_4.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_5.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_5.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_6.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_6.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_7.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_7.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_readme.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature1_file_readme.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+The GenConfML files feature1_file_*.gcfml are intended for testing the
+output locations for gcfml generation.
+
+For quick reference, the folders specified in the data and target
+attributes of the gcfml files are as follows:
+
+num name target
+1
+2 x/
+3 x/y/
+4 a/
+5 a/b/
+6 x/ a/
+7 x/y/ a/b
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature2.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/feature2.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/special_char_test.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/special_char_test.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer2/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer2/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+
+
+
+
+
+ 200
+ layer 2 string
+ 2.005
+ 2
+
+
+
+
+ 222
+ layer2 (1)
+
+
+ 222
+ layer2 (2)
+
+
+ 222
+ layer2 (3)
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer2/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer2/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer2/root_oldmodel.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer2/root_oldmodel.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+
+
+
+ 200
+ layer 2 string
+ 2.005
+ 2
+
+
+
+
+ 222
+ layer2 (1)
+
+
+ 222
+ layer2 (2)
+
+
+ 222
+ layer2 (3)
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer3/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer3/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+
+
+
+ 300
+ layer 3 string
+ 3.005
+ 3
+
+
+
+
+ 333
+ layer3 (1)
+
+
+ 333
+ layer3 (2)
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer3/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer3/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer3/root_oldmodel.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer3/root_oldmodel.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+
+
+
+
+
+ 300
+ layer 3 string
+ 3.005
+ 3
+
+
+
+
+ 333
+ layer3 (1)
+
+
+ 333
+ layer3 (2)
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer4/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer4/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+
+
+
+ 400
+ layer 4 string
+ 4.005
+ 4
+
+
+
+
+ 444
+ layer4 (1)
+
+
+ 444
+ layer4 (2)
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer4/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer4/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer4/root_oldmodel.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer4/root_oldmodel.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+
+
+
+
+
+ 400
+ layer 4 string
+ 4.005
+ 4
+
+
+
+
+ 444
+ layer4 (1)
+
+
+ 444
+ layer4 (2)
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/confml/CVC_2DigitDialing.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/confml/CVC_2DigitDialing.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ 2 Digit Dialing.
+
+ 2 Dialing. Default is disabled
+
+
+
+
+ false
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/confml/commsdatcreator.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/confml/commsdatcreator.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1893 @@
+
+
+ Used to configure whether CommsDat generation from these settings is enabled.
+
+ This is the master switch that determines whether CommsDat is created in the first boot
+ of the device based on Configuration Tool output. Set this to Yes if you are creating variant
+ and need to configure anything under Default CommsDat settings.
+
+
+
+
+ Read-only flag that indicates the CommsDatCreator start-up status in runtime.
+
+
+
+
+ Global networking related settings not tied to individual connection methods.
+
+
+
+ GPRS attach mode (attach when needed/when available).
+
+
+
+
+
+
+ Default GPRS access point. Used when the phone is used as a modem for a PC.
+ The corresponding UI setting is Connection-Packet data-Access point.
+
+
+
+
+ Default icon for destination networks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default priority for LAN bearer type.
+
+
+
+
+ Default priority for WLAN bearer type.
+
+
+
+
+ Default priority for PAN bearer type.
+
+
+
+
+ Default priority for outgoing GPRS bearer type.
+
+
+
+
+ Default priority for incoming GPRS bearer type.
+
+
+
+
+ Default priority for CDMA 2000 bearer type.
+
+
+
+
+ Default priority for outgoing dial bearer type.
+
+
+
+
+ Default priority for incoming dial bearer type.
+
+
+
+
+ Default priority for VPN bearer type.
+
+
+
+
+ Default priority for MIP bearer type.
+
+
+
+
+ Default UI priority of LAN connection.
+
+
+
+
+ Default UI priority for WLAN bearer type.
+
+
+
+
+ Default UI priority for PAN bearer type.
+
+
+
+
+ Default UI priority for outgoing GPRS bearer type.
+
+
+
+
+ Default UI priority for incoming GPRS bearer type.
+
+
+
+
+ Default UI priority for CDMA 2000 bearer type.
+
+
+
+
+ Default UI priority for outgoing dial bearer type.
+
+
+
+
+ Default UI priority for incoming dial bearer type.
+
+
+
+
+ Default UI priority for VPN bearer type.
+
+
+
+
+ Default UI priority for MIP bearer type.
+
+
+
+
+ Specifies how the applications' default connection is specified.
+
+
+
+
+
+
+
+
+ The name of the default connection (connection method or destination network).
+ Default connection type parameter needs to be set accordingly.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when session has closed. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For GPRS the time (in seconds) to stay online when socket has closed. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+ Leave empty to use the product default value.
+
+
+
+
+ How often WLAN networks are scanned when idle.
+
+
+
+
+
+
+
+
+ Defines whether default values are being used for the advanced WLAN settings (recommended).
+
+
+
+
+ Defines how many times packets bigger than RTS Threshold are been resent.
+
+
+ Defines how many times packets smaller than RTS Threshold are been resent.
+
+
+ Minimum size of a packet for which CTS/RTS handshake has been used.
+
+
+ Transmission power level in use. In mWs. 4, 10 or 100 mW.
+
+
+
+
+
+ Defines whether the CCX radio measurements are allowed.
+
+
+
+
+ Defines whether power saving methods are active. Disabling WLAN
+ power save might increase interoperability but will dramatically shorten battery life.
+
+
+
+
+
+ GPRS connection method (CM) definitions
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Addressing that the network uses.
+
+
+
+
+ The access point name for this GPRS connection
+
+
+ User name
+
+
+ Prompt password at connection time.
+
+
+
+
+ Password.
+
+
+ Password authentication method.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method. In URL format.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Allow EDGE usage.
+
+
+
+
+ Specifies the service provider type. Used when filtering connection methods for certain purpose.
+
+
+
+
+
+
+
+ WLAN connection method (CM) definitions
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Service set identifier (SSID) of the primary WLAN network.
+
+
+ Start page of the connection method. In URL format.
+
+
+ Determines the network infrastructure.
+ If there is a WLAN access point in the network then this should be Infrastructure.
+
+
+
+
+ Security mode of the WLAN network.
+
+
+
+
+
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically in which case this should be empty.
+
+
+ The gateway IP address.
+ Typically allocated automatically in which case this should be empty.
+
+
+ Network mask. Typically allocated automatically in which case this should be empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Defines whether the SSID should be actively scanned.
+ This is needed if the SSID is hidden (not broadcasted by the AP)
+
+
+
+
+
+ 802.11 Channel ID (1-14). Used only when connecting/setting up adhoc network.
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Index of default WEP key. Used only when security mode is WEP.
+
+
+
+
+
+
+ WEP authentication mode. Only used when security mode is WEP.
+
+
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WEP key length in bits.
+
+
+
+
+
+ WEP key format.
+
+
+
+
+ WEP key data (in format specified by corresponding WEP key format field).
+
+
+ WPA/WPA2 pre-shared key in plain text. ASCII character set values between 32-126 must be used. Minimum length is 8 characters and maximum 63.
+ You need to also define the WPA pre-shared key length field accordingly
+
+
+ Specifies that when the security mode is WPA or WPA2 if the PSK mode is enabled.
+ If this is off then EAP mode is used and the list of EAPs needs to be defined.
+
+
+
+
+ The length of the specified pre-shared key (in WPA pre-shared key field)
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in use. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM the string needs to be "+018".
+ The list is in priority order, highest priority first.
+
+
+
+ The username used with EAP-GTC.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with EAP-GTC.
+
+
+
+
+
+ The username used with EAP-TLS.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ Defines which EAP tunneling method is used with EAP-TLS.
+
+
+
+
+
+
+ The username used with EAP-LEAP.
+
+
+ The password used with EAP-LEAP.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ The username used with EAP-SIM.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ Defines which EAP tunneling method is used with EAP-SIM.
+
+
+
+
+
+
+ The username used with EAP-TTLS.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TTLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-TTLS. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with EAP-AKA.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with EAP-AKA.
+
+
+
+
+
+
+ The username used with EAP-PEAP.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether PEAP requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ Is PEAP version 0 allowed. If in doubt enable only this one.
+
+
+
+
+ Is PEAP version 1 allowed.
+
+
+
+
+ Is PEAP version 2 allowed.
+
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-PEAP. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with EAP-MSCHAPv2.
+
+
+ The password used with EAP-MSCHAPv2.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ Defines which EAP tunneling method is used with EAP-MSCHAPv2.
+
+
+
+
+
+ The username used with EAP-FAST.
+
+
+ The realm used for device identification to the server.
+
+
+ Specifies whether the server's realm is compared with own realm.
+ This provides extra security but it depends on the network infrastructure and set-up whether this will work.
+
+
+
+
+ Specifies whether TTLS requires that the server authenticates it (the client).
+
+
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear)
+
+
+ The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+ 004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ 019: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+ 050: TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051: TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA
+ For example +004 enables only RSA with RC4 and MD5.
+
+
+
+ A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-FAST. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+ specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018".
+ The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly.
+
+
+ EAP-FAST authenticated provisioning mode allowed
+
+
+
+
+ EAP-FAST unauthenticated provisioning mode allowed
+
+
+
+
+ EAP-FAST warn ADHP no PAC
+
+
+
+
+ EAP-FAST warn ADHP no matching PAC
+
+
+
+
+ EAP-FAST warn not default server
+
+
+
+
+ The subject key id value of the user certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the user certificate. Ignored by the implementation currently!
+
+
+ The serial number of the user certificate. Ignored by the implementation currently!
+
+
+ The subject key id value of the CA certificate.
+ Currently this field is the only one that can be used to identify the certificate.
+
+
+ The issuer of the CA certificate. Ignored by the implementation currently!
+
+
+ The serial number of the CA certificate. Ignored by the implementation currently!
+
+
+ The username used with MSCHAPv2.
+
+
+ The password used with MSCHAPv2.
+
+
+ Specifies how long single session is kept in memory (so no new password queries or similar appear).
+
+
+ Defines which EAP tunneling method is used with MSCHAPv2. Needs to be EAP-TTLS.
+
+
+
+
+
+ Circuit-Switched Data connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Username for the connection.
+
+
+ Prompt password on connection set-up time.
+
+
+
+
+ Password.
+
+
+ Password authentication type.
+
+
+
+
+ WAP gateway IP.
+
+
+ Starting page.
+
+
+ WTLS security.
+
+
+
+
+ Connection type.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Default telephone number.
+
+
+ Bearer speed
+
+
+
+
+
+
+
+
+
+
+ Bearer Call Type Isdn
+
+
+
+
+
+ Is callback enabled.
+
+
+
+
+ Callback type.
+
+
+
+
+ Callback number.
+
+
+ Enable compression
+
+
+
+
+ Use login script
+
+
+
+
+ Login script
+
+
+ Modem init string
+
+
+
+
+ High-speed Circuit-Switched Data connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ User name
+
+
+ Prompt password at connection time.
+
+
+
+
+ Password.
+
+
+ Password authentication method.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ Default telephone number.
+
+
+ Bearer speed
+
+
+
+
+
+
+
+
+
+
+ Bearer Call Type Isdn
+
+
+
+
+
+ Is callback enabled.
+
+
+
+
+ Callback type.
+
+
+
+
+ Callback number.
+
+
+ Enable compression
+
+
+
+
+ Use login script
+
+
+
+
+ Login script
+
+
+ Modem init string
+
+
+
+
+ LAN connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ WAP gateway IP address.
+
+
+ Start page of the connection method.
+
+
+ Attempts a secure WTLS connection to the gateway.
+
+
+
+
+ Indicates whether a connection-oriented or connectionless API should be used.
+
+
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ LAN interface networks.
+
+
+ LAN interface netmask.
+
+
+ LAN IP Gateway.
+
+
+ IP address of the interface.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the primary DNS server that resolves host names.
+ Typically allocated automatically so this can be left empty.
+
+
+ Address of the secondary DNS server to connect if the primary DNS server is not available.
+ Typically allocated automatically so this can be left empty.
+
+
+
+
+ Virtual Private Network connection methods
+
+
+ The CM name that is visible to the user.
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Defines whether connection method is protected (= cannot be edited by the user).
+
+
+
+
+ Defines whether connection method is hidden.
+
+
+
+
+ Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).
+
+
+
+
+ Connection method is highlighted or not.
+
+
+
+
+ Defines whether an IAP can be roamed to.
+
+
+
+
+ Address of the HTTP/HTTPS proxy server.
+
+
+ Port number of the HTTP/HTTPS proxy server.
+
+
+ Name of the protocol for which this proxy can be used.
+ Typically http or https.
+
+
+ The network connection provider IAP name.
+
+
+ Service policy.
+
+
+
+
+ Destination network (SNAP) definitions.
+
+
+ The name that is visible to the user
+
+
+ The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+ Note: It needs to be verified carefully that the IDs are globally unique if allocated manually!
+ So a good idea is to either specify all the IDs manually or none at all.
+
+
+ Metadata that specifies a few default destination networks that applications can use
+
+
+
+
+
+
+
+ DN protection level. Destination contents mean the connection methods inside the destination and their priorities.
+
+
+
+
+
+ Is DN hidden or not.
+
+
+
+
+ Is DN hidden in CConnDlg or not
+
+
+
+
+ Is DN highlighted or not.
+
+
+
+
+ Icon to be assigned to DN.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of an embedded DN that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+ Name of the Connection Method that is bound to DN.
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ Normal
+ On
+ Continuous
+ Autodetect
+ Analogue
+ Yes
+ Server Number
+ No
+ No
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User Defined
+ 0
+ No
+ No
+ No
+ 11
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Internet
+ 1
+ Internet
+ 2
+ No
+ No
+ Yes
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MMS
+ 2
+ MMS
+ 2
+ No
+ Yes
+ No
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Operator
+ 3
+ Operator
+ 2
+ No
+ No
+ No
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ whenavailable
+ 11
+ Ask once
+
+
+ 1
+ 0
+ 100
+ 1
+ 1
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 253
+ 254
+ 9
+ 0
+ 8
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 4
+ 7
+ 2347
+ 300
+ 1
+ 300
+ -1
+ 1
+ -1
+ -1
+ 1
+ -1
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ IPv4
+ No
+ Normal
+ On
+ Continuous
+ Yes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ No
+ Normal
+ On
+ Continuous
+ Autodetect
+ Analogue
+ Yes
+ Server Number
+ No
+ No
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ Confirm first
+ On
+ Continuous
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+ Infrastructure
+ Open
+ No
+ key1
+ Shared
+ 64
+ ASCII
+ 64
+ ASCII
+ 64
+ ASCII
+ 64
+ ASCII
+ No
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No
+ No
+ No
+ No
+ ConfirmFirst
+
+
+
+
+
+
+
+
+
+
+ 0
+ VariantData_commsdat.xml
+
+
+
+
+ false
+ false
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/confml/predefinedcontacts.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/confml/predefinedcontacts.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hao
+ Rich
+ Neusoft
+
+ 011
+ 022
+ 033
+ 044
+ rich@neusoft.com
+
+
+ 2
+ videono
+
+
+ Kevin
+ Chong
+ Neusoft
+ Engineer
+ 11
+ 22
+ 33
+ 44
+ Kevin@neusoft.com
+ 3
+ mob
+
+
+
+
+ Feng
+ Chen
+ Neusoft
+ 135
+
+
+ 138
+ 4
+ fax
+
+
+
+
+
+
+ Heng
+ Xia
+ HenNuo
+ Manager
+ 010
+ 020
+ 040
+ 030
+ wllx@neusoft.com
+ 5
+ email
+
+
+
+
+ Bo
+ Zhang
+ 110
+ 120
+ 6
+
+
+
+
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Codo
+ Kiki
+ Neusoft
+ 32
+ 54
+ 65
+ 65
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \private\2000BEE5\
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/implml/file1.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/implml/file1.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/implml/predefinedcontacts.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/implml/predefinedcontacts.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_2DigitDialing.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_2DigitDialing.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ 2 Digit Dialing.
+
+ 2 Dialing. Default is disabled
+
+
+
+
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ActiveIdleNotifiers.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ActiveIdleNotifiers.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+
+
+ Notification components: missed calls, new messages (device inbox), and new voice messages are located on one row of the device. It is possible to configure the notifiers on/off separately. If a notification component is turned off, the notifications are shown as traditional pop-up notifications.
+
+ Up to two different e-mail accounts for each mode can be configured to be visible on the Home screen. It is not possible to customize e-mail notifiers as they are only available when the e-mail account is first activated.
+
+
+ Calendar and To-do components provide dynamically updated information from Calendar entries and ToDo notes. If there is no data to show, "No calendar events for today" note is visible on the Home screen view.
+
+
+ The Music Player component shows the music tracks that are being played by the Music Player. If there is no data to show, this UI area is empty.
+
+
+ The Visual radio plug-in shows the name or frequency of the radio channel that is being played by Visual radio in the background. The icon also shows whether Visual radio service is available for the current channel.
+
+
+ This component shows dynamically updated information about available WLAN networks and shortcut to WLAN wizard that enables selecting WLAN network and defining access point for it. If scanning is set to off, there is 'WLAN scanning off' in Home screen view.
+
+
+ This component shows dynamically updated information about available WLAN networks and shortcut to WLAN wizard that enables selecting WLAN network and defining access point for it. If scanning is set to off, there is 'WLAN scanning off' in Home screen view.
+
+
+ This plug-in provides easy access to Voice over IP settings wizard, providing options to launch Voice over IP setup wizard or hide the plug-in from the Home screen.
+
+
+ The Mobile search plug-in allows the user to initiate a search for content in the device or in the Internet directly from Home screen. User can click on the plug-in and write the search term.
+
+
+ The SIM Application Toolkit shows messages from an application residing on the SIM card.
+
+
+
+
+true
+true
+true
+true
+true
+true
+true
+true
+true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ActiveIdleOther.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ActiveIdleOther.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+ Easy Dialing allows user to start dialling from Home Screen to a contact without first starting Phonebook application. The name input is predictive (subject to restrictions by input language), and the contacts are matched so that each character only requires one key press. Typing more narrows down the options. User is able to use the number that was just typed, or select one of the name matches.
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_CPHSALS.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_CPHSALS.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ CPHS is an extension to the GSM specification that adds several convenience and usability enhancements to the way GSM phones and SIM cards operate. Examples of CPHS enhancements include single-key access to a standard voicemail number stored on the SIM, and a message-waiting indicator to alert users to new voicemail messages. CPHS also provides carriers with greater control and flexibility over the carrier name that is displayed on the phone. CPHS also includes the ability to control certain network-based features from the phone interface, including call forwarding, call waiting, and caller-ID. CPHS is not an official part of the GSM specification. It was developed by the PCN Association rather than the GSM Association. Nonetheless, CPHS has been popular among carriers. Many European and American GSM carriers require it, and so newer GSM phones from most major manufacturers include CPHS functionality.
+
+ If ALS is set as ON, the functionality of toggling from General to Silent profile by long press # key will be disabled. CPHS and ALS can be set ON and OFF in the customer variants of the standard transceiver. CPHS and ALS can never be both set ON at the same time.
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_CellInfoDisplay.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_CellInfoDisplay.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ Cell Info Display Setting (Cell Broadcast Reception)
+
+ Cell Info Display Setting (Cell Broadcast Reception). "On" when checked. Cell info display is "Off" by default in the standard transceiver. This setting is set "On" by default for countries in which the GSM regulatory authority requires it.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_CustomerMenu.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_CustomerMenu.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+
+
+ Often referred to as the Operator Menu, the Customer Menu is an application that launches the browser as an embedded application with a predefined URL as parameter. The URL defines the xHTML Startup page that is shown when the Customer Menu application is launched, for example www.customername.com/index.html. The URL also defines the customer domain URL path, for example www.customername.com/. All user-browsed xHTML pages belonging to that path are automatically stored in the Customer Menu cache.The Customer Menu application can be configured as a shortcut just like any other application. In Main menu, the Customer Menu is placed by default to 11th position. When the Customer Menu is enabled, Help moves from position 11 to 12 and Apps moves from 12 to 13, which is not visible until the user scrolls the menu cursor.
+
+ Customer menu icon that will be present in Application Grid. Size: 65 x 65 pixels. Format: SVGT (preferred) or BMP. Color depth: 24 bit
+
+
+ Customer menu bitmask when using BMP menu icon. Size: 65 x 65 pixels. Format: BMP. Color depth: 8 bit
+
+
+ The text caption for Customer Menu icon
+
+
+ Target URL for Operator Menu. The URL defines the xHTML Start-up page that will be shown when the Customer Menu application is launched (e.g. “www.customername.com/index.htmâ€). The URL also defines the customer domain URL path (e.g. “www.customername.comâ€).
+
+
+ Data stored in the Customer Menu cache is preserved in the device memory and can be accessed even after the Browser session is ended and through power cycles of the device. File format: xHTML files. Customers provide the xHTML pages to be pre-installed in the Customer Menu Cache.The max. amount of data that can be stored in the Customer Menu cache is 300 KB
+
+
+ In “mm/yyyy†format. Customers define the expiration date of the xHTML page(s). After that date, the cache content will no longer be used and Operator icon will launch URL instead.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_InstantMessaging.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_InstantMessaging.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,72 @@
+
+
+
+ IM (Instant Messaging) settings
+
+ Server name. Max 30 chars.
+
+
+ Max 100 chars.
+
+
+ Max 50 chars.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Alert tone for Instant Messaging.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_NokiaPCInternetAccess.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_NokiaPCInternetAccess.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+Customizations of PC application "Nokia PC Internet Access"
+
+ Customer logo file. Format: Portable Network Graphics with transparent background. Size 280x40.
+
+
+
+ NPCIA autolaunches the default web browser of the PC. Default starting page of the browser can be set through NPCIA (when browser is launched by NPCIA)
+
+
+
+ Located in in NPCIAs’ ‘Settings’ view. Can be phone number and/or link to operator webpage.
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_OperatorLogo.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_OperatorLogo.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+The Nokia E75 supports color logos in addition to the traditional black and white customer logos. Customer logos may be predefined in the default settings for the device or downloaded by the user. The customer logo is stored together with the MNC and MCC info of the home network in the device and will be displayed when the user is in the home network. The customer logo replaces the standard customer name.
+
+ Operator logo file. Format: BMP or SVG. Maximum size 134x33 pixels. Name must be Logo_MCC_MNC_PROG.svg or Logo_MCC_MNC_PROG.bmp, where MCC and MNC are mobile country code and mobile network code.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_Preinstalled.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_Preinstalled.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,117 @@
+
+
+ Customer-defined pre-installed content. Please note that the total size of the User Data Area content size must not exceed 5 Mbytes.
+
+ Max 6 mms, max size 35K. Binary format (encoding according to MMS encapsulation specification)
+
+ Pre-Installed MMS
+
+
+
+ Pre-Installed Images. Size up to 5MP (2560x1920 pixels), format JPEG. No EXIF data allowed
+
+
+ Pre-Installed Streaming links. Format is .ram file.
+
+
+ Pre-Installed Music Clips.
+
+
+ Pre-Installed Video Clips.
+
+
+ Default Ringtone in General Profile. Any supported media file.
+
+
+ Default ringtone for incoming message event in General Profile. Any supported media file.
+
+
+ Default ringtone for video call event in General Profile. Any supported media file.
+
+
+ Pre-Installed Themes. Format is Theme project archive zip file with extesion .tpf, containing the theme project and main .tdf file.
+
+
+ Complementary applications pre-Installed to device ROM. Will NOT be uninstallable by end-users. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+ Complementary applications pre-Installed to device ROM. Will NOT be uninstallable by end-users. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+ Complementary applications pre-loaded to device. Offerecd for installation to the end-user. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+ Symbian certificates for trusted software installations.
+
+
+ Certificate file. Must be in X.509 CA format.
+
+
+ Allows installation of native Symbian OS applications (on/off)
+
+
+ Allows to validate OCSP revocation responses (on/off)
+
+
+
+
+ Java MIDP certificates for trusted software installations.
+
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+ Trusted application domain: Customer or Third-party.
+
+
+
+
+
+
+ Certificates for Internet services: SSL/TLS (HTTPS,SecureIMAP, etc.) connections.
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+ Allows to validate OCSP revocation responses (on/off)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_RightSoftkey.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_RightSoftkey.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+
+
+ The right soft key (RSK) in idle mode can be configured to launch a customer defined application or URL. The RSK label can be branded with a graphic only if it is a URL. The left soft key (LSK) is always a text string and is not customizable. The end user is able to personalize both the left and right soft keys.
+
+ Right Softkey Customization
+
+
+ Right Softkey caption text (if RSK is not customized as image). 12 characters max (5 for Chinese variants).
+
+
+ Size: 115 x 22 pixels Format: SVGT (preferred) or BMP
+
+
+ Right softkey BMP mask. Applicable only if BMP format is used.
+
+
+ Right Softkey target URL (if target is defined as a web site).
+
+
+ Right Softkey target Application UID (if target is an application). Format is a hexadecimal number (0x00000000).
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_StartupShutdownAnimations.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_StartupShutdownAnimations.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,43 @@
+
+
+ Startup animation. The customer specific startup element can contain either a still image or an animation with or without a customer specified tone.
+
+ Display time for still image is max 3 seconds, for animation 2.5 max seconds.
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+ Shutdown animation. The customer specific shutdown element can contain either a still image or an animation with or without a customer specified tone.
+
+ Display time for still image is max 3 seconds, for animation 2.5 max seconds.
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+
+ 3000
+
+
+
+
+
+
+ 3000
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_Streaming.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_Streaming.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,123 @@
+
+
+ Streaming Settings
+
+ Use proxy for streaming
+
+
+
+
+ Programmed (max.length 1000 characters)
+
+
+ Programmed (1-9999)
+
+
+ Programmed (max.length 100 characters)
+
+
+ Limit for online time spent in streaming
+
+
+
+
+ User-selectable value for online streaming time (if limiting is enabled)
+ (1 – 30 minutes)
+
+
+ 1024 (equal or smaller than Highest UDP port) (default 6970)
+
+
+ 65535 (equal or bigger than Lowest UDP port)(default 32000)
+
+
+ GPRS bandwidth limit for streaming
+
+
+
+
+
+
+
+
+ User defined (5 – 99.99 kbps)
+
+
+ EGPRS bandwidth limit for streaming
+
+
+
+
+
+
+
+ User defined (5 – 199.99 kbps)
+
+
+ UMTS bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+ User defined (5 – 999.99 kbps)
+
+
+ WLAN bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User defined (kbps)
+
+
+ HSDPA bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+ User defined (5 – 3999.99 kbps)
+
+
+
+
+ No
+
+ 554
+
+ Unlimited
+ 1
+ 6970
+ 32000
+ 40
+ 5
+ 89
+ 5
+ 384
+ 5
+ 1430
+ 5
+ user
+ 5
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_SyncML.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_SyncML.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,161 @@
+
+
+ SyncML Settings.
+
+ Maximum length 50 characters.
+
+
+ 1.1, 1.2 (default)
+
+
+
+
+ Server ID
+
+
+ Data bearer for server connection
+
+
+
+
+
+ Access point to use for server connetion
+
+
+
+
+ Maximum length 150 characters.
+
+
+ 80 (default), 1-65535
+
+
+ Server account: username
+
+
+ Server account: password
+
+
+ Policy for sync requests
+
+
+
+
+
+ Username for Access Point connection
+
+
+ Password for Access Point connection
+
+
+ Type of syncronization
+
+
+
+
+
+
+
+
+
+ Include Contacts in Sync ON/OFF
+
+
+
+ Include Calendar in Sync ON/OFF
+
+
+
+ Include Notes in Sync ON/OFF
+
+
+
+ Include E-mail in Sync ON/OFF
+
+
+
+ Include Music in Sync ON/OFF
+
+
+
+ Include MSyncService in Sync ON/OFF
+
+
+
+ Include Images in Sync ON/OFF
+
+
+
+ Include MMS in Sync ON/OFF
+
+
+
+ Include Video in Sync ON/OFF
+
+
+
+ Include SMS in Sync ON/OFF
+
+
+
+ Include Bookmarks in Sync ON/OFF
+
+
+
+
+
+
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+
+
+
+80
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ThemeWallpaperScreensaver.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ThemeWallpaperScreensaver.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+
+
+
+ Default Theme to be set on device. Select from the set of pre-installed themes.
+
+ Default Theme to be set on device. Select from the set of pre-installed themes.
+
+
+
+
+ Default wallpaper
+
+ Size: 240X234 pixels Format: SVGT (preferred) or BMP. 24 bit. The end user can select to change this to either a different single image or select multiple images to run in a wallpaper slide show.
+
+
+
+
+ Screensaver
+
+ Screensaver file. Format is animated GIF.
+
+
+ Duration the animation will run before reverting to default screensaver in minutes. Min 1 minute, max 30 minutes.
+
+
+ Duration of display lights being turned on while the animation runs in seconds. 0 = no lights, max 30 seconds.
+
+
+
+
+3
+15
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_VoiceMailbox.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_VoiceMailbox.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ The device number of the customer’s voice mailbox may be programmed into the device during production or in service. Voice mailbox feature may be activated in two different ways: CSP (Customer Service Profile) support is enabled in product profile AND voice mailbox numbers can be found from customer’s SIM card
+
+ Maximum allowed length is 50 characters.
+
+
+ Maximum allowed length is 50 characters.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ZeroPlusSend.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/CVC_ZeroPlusSend.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ 0 + SEND is used in the US as access number to national operator assistance both in landline and wireless networks.
+
+ 0 + SEND is used in the US as access number to national operator assistance both in landline and wireless networks. Default is off.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/cvc_view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/confml/cvc_view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/cvc_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/cvc/cvc_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/family/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/family/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/family/product/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/family/product/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/family/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/family/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/product.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/product.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root2.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root2.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root3.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root3.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root4.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root4.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root_cvc.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/root_cvc.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ Customer-independent
+ 2008-11-21
+ Me
+ cvc
+ Me
+ S60
+ P1
+ PR0
+ Draft
+ 0.1
+
+ Custom ConfMLs for P1
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_confflattener.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_confflattener.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,119 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+import copy
+
+import __init__
+from genconfmlplugin import confflattener
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'project')
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+class TestGenconfmlPlugin(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = 'output'
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_flat(self):
+ '''
+ Test that the configuration flattening works
+ '''
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ flat = p.create_configuration('flat.confml')
+ dview = config.get_default_view()
+ for fea in dview.get_features('**'):
+ newfea = copy.copy(fea._obj)
+ flat.add_feature(newfea, fea.namespace)
+ toview = flat.get_default_view()
+ for fea in toview.get_features('**'):
+ fromfea = dview.get_feature(fea.fqr)
+ if fromfea.get_value() != None:
+ fea.set_value(fromfea.get_value())
+ flat.close()
+ config.close()
+
+ config = p.get_configuration('product.confml')
+ flat = p.get_configuration('flat.confml')
+ fdview = flat.get_default_view()
+ for fea in config.get_default_view().get_features('**'):
+ self.assertEquals(fea.get_value(),fdview.get_feature(fea.fqr).get_value())
+
+ pass
+
+ def test_flat2(self):
+ '''
+ Test that the configuration flattening works
+ '''
+ fs = filestorage.FileStorage(testdata,"a")
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ confflat = confflattener.ConfigurationFlattener()
+ confflat.create_configuration(config, ['DNs/**'],"tempfile2.confml")
+ config = p.get_configuration('root_cvc.confml')
+ dview = config.get_default_view()
+ flat = p.get_configuration('tempfile2.confml')
+ fdview = flat.get_default_view()
+ for fea in fdview.get_features('**'):
+ self.assertEquals(fea.get_value(),dview.get_feature(fea.fqr).get_value())
+ dataconf = flat.get_configuration('tempfile2_data.confml')
+ fearefs = fdview.list_all_features()
+ for dataref in dataconf.list_all_datas():
+ self.assertTrue(dataref in fearefs,"%s not in %s" % (dataref,fearefs))
+
+ def test_flat3(self):
+ '''
+ Test that the configuration flattening works
+ '''
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ confflat = confflattener.ConfigurationFlattener()
+ confflat.create_configuration(config, ['Contacts/Contact'],"contacts_flat.confml")
+
+ config = p.get_configuration('product.confml')
+ dview = config.get_default_view()
+ flat = p.get_configuration('contacts_flat.confml')
+ fdview = flat.get_default_view()
+ for fea in fdview.get_features('**'):
+ self.assertEquals(fea.get_value(),dview.get_feature(fea.fqr).get_value())
+ dataconf = flat.get_configuration('contacts_flat_data.confml')
+ fearefs = fdview.list_all_features()
+ for dataref in dataconf.list_all_datas():
+ self.assertTrue(dataref in fearefs,"%s not in %s" % (dataref,fearefs))
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_gcfml_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_gcfml_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,168 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+
+import __init__
+from genconfmlplugin import genconfmlplugin
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'project')
+
+invalidxml_string = ''
+genconfgml_string = \
+''\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '\
+' '
+
+
+
+class TestGenconfmlPlugin(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = os.path.join(ROOT_PATH, 'temp/output')
+
+ def test_example_parse_and_generate_prj2(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('root1.confml')
+ impls = plugin.get_impl_set(config,'\.gcfml$')
+ impls.output = self.output
+ impl = impls.get_implementations_by_file('Layer1/implml/feature1.gcfml')[0]
+ impls.generate()
+
+ def test_predefined_contacts_parse_and_generate(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impls = plugin.get_impl_set(config,'\.gcfml$')
+ impls.output = self.output
+ impl = impls.get_implementations_by_file('assets/s60/implml/predefinedcontacts.gcfml')[0]
+ impls.generate()
+
+ def test_write_element_fo_file(self):
+ '''
+ Fix this
+ '''
+ OUTFILE = os.path.join(ROOT_PATH, 'temp/elementfile.xml')
+ if not os.path.exists(os.path.join(ROOT_PATH, 'temp')):
+ os.makedirs(os.path.join(ROOT_PATH, 'temp'))
+ #fs = filestorage.FileStorage(testdata)
+ #p = api.Project(fs)
+ #config = p.get_configuration('product.confml')
+ #genconfml_plugin = genconfmlplugin.GenconfmlImpl(None, config)
+ element = ElementTree.fromstring('kfkadl ')
+
+ genconfmlplugin.write_element(element, OUTFILE)
+ self.assertTrue(os.path.exists(OUTFILE))
+ #out_file = open(output, 'r')
+ #out_file.write(xml.etree.ElementTree.tostring(element))
+ #out_file.close()
+
+
+ #resource = self.configuration.get_resource("elementfile.xml")
+
+
+ def test_parse_target(self):
+ etree = ElementTree.fromstring(genconfgml_string)
+ reader = genconfmlplugin.GenconfmlImplReader()
+ target = reader.parse_target(etree)
+ self.assertEquals(target,'output')
+
+ def test_parse_stylesheet(self):
+ etree = ElementTree.fromstring(genconfgml_string)
+ reader = genconfmlplugin.GenconfmlImplReader()
+ stylesheet = reader.parse_stylesheet(etree)
+ #print stylesheet
+ #FIX THIS
+ #self.assertEquals(stylesheet, etree.find("{%s}stylesheet" % 'http://www.w3.org/1999/XSL/Transform'))
+
+ def test_parse_name(self):
+ etree = ElementTree.fromstring(genconfgml_string)
+ reader = genconfmlplugin.GenconfmlImplReader()
+ name = reader.parse_name(etree)
+ self.assertEquals(name,'Setting/Data.xml')
+
+ def test_parse_subdir_without_definition(self):
+ etree = ElementTree.fromstring(genconfgml_string)
+ reader = genconfmlplugin.GenconfmlImplReader()
+ subdir = reader.parse_subdir(etree)
+ self.assertEquals(subdir, "")
+
+ def test_parse_subdir_with_definition(self):
+ etree = ElementTree.fromstring(genconfgml_string.replace("target=\"output\"", "subdir=\"include\""))
+ reader = genconfmlplugin.GenconfmlImplReader()
+ subdir = reader.parse_subdir(etree)
+ self.assertEquals(subdir, "include")
+
+ def test_parse_settings(self):
+ etree = ElementTree.fromstring(genconfgml_string)
+ reader = genconfmlplugin.GenconfmlImplReader()
+ settings = reader.parse_settings(etree)
+ self.assertEquals(settings[0],'Setting/Settings')
+ self.assertEquals(settings[1],'Setting/ContentSettings')
+
+ def test_has_ref(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impls = plugin.get_impl_set(config,'\.gcfml$')
+ impls.output = self.output
+ impl = impls.get_implementations_by_file('assets/s60/implml/predefinedcontacts.gcfml')[0]
+ self.assertEquals(impl.get_refs(), ['Contacts.Contact'])
+ self.assertFalse(impl.has_ref(['ref1', 'ref2']))
+ self.assertTrue(impl.has_ref(['Contacts.Contact']))
+ self.assertTrue(impl.has_ref(['Contacts.Contact.FirstName']))
+ self.assertFalse(impl.has_ref(['Contacts.OtherSetting']))
+
+ def test_list_output_files(self):
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impls = plugin.get_impl_set(config,'\.gcfml$')
+ impls.output = self.output
+ impl = impls.get_implementations_by_file('assets/s60/implml/predefinedcontacts.gcfml')[0]
+ self.assertEquals(impl.list_output_files(), ['output\\private\\2000BEE5\\predefinedcontacts.xml'])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_generation.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_generation.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import exceptions, plugin, api, container
+
+def abspath(path):
+ return os.path.normpath(os.path.join(ROOT_PATH, path))
+
+class TestGenconfmlGeneration(BaseTestCase):
+
+ def test_generate_gcfml_layer1(self): self._run_gen_test(1)
+ def test_generate_gcfml_layer2(self): self._run_gen_test(2)
+ # Related to the ignored file, see ticket #160: Sequence items with extension policy prefix are reversed
+ def test_generate_gcfml_layer3(self): self._run_gen_test(3, ignores=['feature2.txt'])
+ def test_generate_gcfml_layer4(self): self._run_gen_test(4)
+
+ def _run_gen_test(self, layer, ignores=[]):
+ project_dir = abspath('project')
+ config = 'root%s.confml' % layer
+ output_dir = abspath('temp/gen_output%s' % layer)
+ expected_dir = abspath('expected/root%s' % layer)
+
+ self.remove_if_exists(output_dir)
+
+ prj = api.Project(api.Storage.open(project_dir))
+ config = prj.get_configuration(config)
+ impls = plugin.get_impl_set(config, 'gcfml$')
+ impls.output = output_dir
+ impls.generate()
+
+ self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'] + ignores)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_xslttransformer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_xslttransformer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil, sys
+
+import __init__
+from genconfmlplugin import xslttransformer
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'project')
+
+class TestGenconfmlPlugin(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = 'output'
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_transform(self):
+ '''
+ Test that the xslt transformation works
+ '''
+ transformer = xslttransformer.XsltTransformer()
+ transformer.transform_lxml(os.path.join(ROOT_PATH,"xslt\cdcatalog.xml"),
+ os.path.join(ROOT_PATH,"xslt\cdcatalog_ex1.xsl"),
+ "testioutput.xml",
+ sys.getdefaultencoding())
+ os.unlink("testioutput.xml")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/xslt/cdcatalog.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/xslt/cdcatalog.xml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,211 @@
+
+
+
+ Empire Burlesque
+ Bob Dylan
+ USA
+ Columbia
+ 10.90
+ 1985
+
+
+ Hide your heart
+ Bonnie Tyler
+ UK
+ CBS Records
+ 9.90
+ 1988
+
+
+ Greatest Hits
+ Dolly Parton
+ USA
+ RCA
+ 9.90
+ 1982
+
+
+ Still got the blues
+ Gary Moore
+ UK
+ Virgin records
+ 10.20
+ 1990
+
+
+ Eros
+ Eros Ramazzotti
+ EU
+ BMG
+ 9.90
+ 1997
+
+
+ One night only
+ Bee Gees
+ UK
+ Polydor
+ 10.90
+ 1998
+
+
+ Sylvias Mother
+ Dr.Hook
+ UK
+ CBS
+ 8.10
+ 1973
+
+
+ Maggie May
+ Rod Stewart
+ UK
+ Pickwick
+ 8.50
+ 1990
+
+
+ Romanza
+ Andrea Bocelli
+ EU
+ Polydor
+ 10.80
+ 1996
+
+
+ When a man loves a woman
+ Percy Sledge
+ USA
+ Atlantic
+ 8.70
+ 1987
+
+
+ Black angel
+ Savage Rose
+ EU
+ Mega
+ 10.90
+ 1995
+
+
+ 1999 Grammy Nominees
+ Many
+ USA
+ Grammy
+ 10.20
+ 1999
+
+
+ For the good times
+ Kenny Rogers
+ UK
+ Mucik Master
+ 8.70
+ 1995
+
+
+ Big Willie style
+ Will Smith
+ USA
+ Columbia
+ 9.90
+ 1997
+
+
+ Tupelo Honey
+ Van Morrison
+ UK
+ Polydor
+ 8.20
+ 1971
+
+
+ Soulsville
+ Jorn Hoel
+ Norway
+ WEA
+ 7.90
+ 1996
+
+
+ The very best of
+ Cat Stevens
+ UK
+ Island
+ 8.90
+ 1990
+
+
+ Stop
+ Sam Brown
+ UK
+ A and M
+ 8.90
+ 1988
+
+
+ Bridge of Spies
+ T`Pau
+ UK
+ Siren
+ 7.90
+ 1987
+
+
+ Private Dancer
+ Tina Turner
+ UK
+ Capitol
+ 8.90
+ 1983
+
+
+ Midt om natten
+ Kim Larsen
+ EU
+ Medley
+ 7.80
+ 1983
+
+
+ Pavarotti Gala Concert
+ Luciano Pavarotti
+ UK
+ DECCA
+ 9.90
+ 1991
+
+
+ The dock of the bay
+ Otis Redding
+ USA
+ Atlantic
+ 7.90
+ 1987
+
+
+ Picture book
+ Simply Red
+ EU
+ Elektra
+ 7.20
+ 1985
+
+
+ Red
+ The Communards
+ UK
+ London
+ 7.80
+ 1987
+
+
+ Unchain my heart
+ Joe Cocker
+ USA
+ EMI
+ 8.20
+ 1987
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/xslt/cdcatalog_ex1.xsl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/xslt/cdcatalog_ex1.xsl Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+
+ My CD Collection
+
+
+ Title
+ Artist
+
+
+ .
+ .
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/xslt/cdcatalog_with_ex1.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/xslt/cdcatalog_with_ex1.xml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,212 @@
+
+
+
+
+ Empire Burlesque
+ Bob Dylan
+ USA
+ Columbia
+ 10.90
+ 1985
+
+
+ Hide your heart
+ Bonnie Tyler
+ UK
+ CBS Records
+ 9.90
+ 1988
+
+
+ Greatest Hits
+ Dolly Parton
+ USA
+ RCA
+ 9.90
+ 1982
+
+
+ Still got the blues
+ Gary Moore
+ UK
+ Virgin records
+ 10.20
+ 1990
+
+
+ Eros
+ Eros Ramazzotti
+ EU
+ BMG
+ 9.90
+ 1997
+
+
+ One night only
+ Bee Gees
+ UK
+ Polydor
+ 10.90
+ 1998
+
+
+ Sylvias Mother
+ Dr.Hook
+ UK
+ CBS
+ 8.10
+ 1973
+
+
+ Maggie May
+ Rod Stewart
+ UK
+ Pickwick
+ 8.50
+ 1990
+
+
+ Romanza
+ Andrea Bocelli
+ EU
+ Polydor
+ 10.80
+ 1996
+
+
+ When a man loves a woman
+ Percy Sledge
+ USA
+ Atlantic
+ 8.70
+ 1987
+
+
+ Black angel
+ Savage Rose
+ EU
+ Mega
+ 10.90
+ 1995
+
+
+ 1999 Grammy Nominees
+ Many
+ USA
+ Grammy
+ 10.20
+ 1999
+
+
+ For the good times
+ Kenny Rogers
+ UK
+ Mucik Master
+ 8.70
+ 1995
+
+
+ Big Willie style
+ Will Smith
+ USA
+ Columbia
+ 9.90
+ 1997
+
+
+ Tupelo Honey
+ Van Morrison
+ UK
+ Polydor
+ 8.20
+ 1971
+
+
+ Soulsville
+ Jorn Hoel
+ Norway
+ WEA
+ 7.90
+ 1996
+
+
+ The very best of
+ Cat Stevens
+ UK
+ Island
+ 8.90
+ 1990
+
+
+ Stop
+ Sam Brown
+ UK
+ A and M
+ 8.90
+ 1988
+
+
+ Bridge of Spies
+ T`Pau
+ UK
+ Siren
+ 7.90
+ 1987
+
+
+ Private Dancer
+ Tina Turner
+ UK
+ Capitol
+ 8.90
+ 1983
+
+
+ Midt om natten
+ Kim Larsen
+ EU
+ Medley
+ 7.80
+ 1983
+
+
+ Pavarotti Gala Concert
+ Luciano Pavarotti
+ UK
+ DECCA
+ 9.90
+ 1991
+
+
+ The dock of the bay
+ Otis Redding
+ USA
+ Atlantic
+ 7.90
+ 1987
+
+
+ Picture book
+ Simply Red
+ EU
+ Elektra
+ 7.20
+ 1985
+
+
+ Red
+ The Communards
+ UK
+ London
+ 7.80
+ 1987
+
+
+ Unchain my heart
+ Joe Cocker
+ USA
+ EMI
+ 8.20
+ 1987
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/xslttransformer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/xslttransformer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,168 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+Configuration flattener
+'''
+
+
+import re
+import os
+import sys
+import codecs
+import logging
+import xml.parsers.expat
+import unittest, os, sys, pkg_resources
+
+pkg_resources.require('lxml')
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+
+class XsltTransformer():
+ """
+ XSLT Transformer
+ """
+
+ def _init(self,ref,configuration):
+ self.logger = logging.getLogger('cone.gcfml(%s)' % self.ref)
+
+
+ def transform_lxml(self, input, xslt, output, enc, linesep=os.linesep):
+ """
+ XSLT transform with lxml.
+ """
+ from lxml import etree
+
+ if not enc:
+ enc = sys.getdefaultencoding()
+ try:
+ xslt_doc = etree.parse(xslt)
+ transform = etree.XSLT(xslt_doc)
+
+ input_doc = etree.parse(input)
+ result = str(transform(input_doc))
+ postprocessed_result = post_process_result(result, enc, linesep)
+
+ if not filter_file_writing(postprocessed_result):
+ write_string_to_file(postprocessed_result, output, enc)
+
+ except Exception, e:
+ logging.getLogger('cone.gcfml').error('Failed to do XSLT transformation: %s' % e)
+ raise exceptions.ConeException('Failed to do XSLT transformation: %s' % (e))
+
+
+ def transform_4s(self, input, xslt, output, enc, linesep=os.linesep):
+ """
+ XSLT transform with 4Suite
+ """
+ from Ft.Xml.Xslt import Transform
+ from Ft.Xml.Xslt import Processor
+ from Ft.Xml import InputSource
+ from Ft.Lib.Uri import OsPathToUri
+
+
+ if not enc:
+ enc = sys.getdefaultencoding()
+
+ try:
+ processor = Processor.Processor()
+
+ srcAsUri = OsPathToUri(input)
+ source = InputSource.DefaultFactory.fromUri(srcAsUri)
+
+ ssAsUri = OsPathToUri(xslt)
+ transform = InputSource.DefaultFactory.fromUri(ssAsUri)
+
+ processor.appendStylesheet(transform)
+ result = processor.run(source)
+
+ postprocessed_result = post_process_result(result, enc, linesep)
+
+ if not filter_file_writing(postprocessed_result):
+ write_string_to_file(postprocessed_result, output, enc)
+
+ except Exception, e:
+ logging.getLogger('cone.gcfml').error('Failed to do XSLT transformation: %s' % e)
+ raise exceptions.ConeException('Failed to do XSLT transformation: %s' % (e))
+
+def filter_file_writing(string):
+ """
+ Returns True if writing result file should be ignored.
+ """
+ string = string.rstrip('\n\r')
+ if string == '' or string == '' or \
+ string == '':
+ return True
+
+ return False
+
+
+def post_process_result(string, enc, linesep):
+ """
+ Does post process for result from XSLT transform
+ - encoding
+ - removes extra line separators
+ - changes line separators
+ """
+ output_string = None
+
+ try:
+ output_string = string.decode(enc)
+ if not output_string.startswith('<'):
+ output_string = '\n' + output_string
+ output_string = output_string.replace('', '\n\n')
+ output_string = output_string.replace('', '\n\n')
+ output_string = output_string.replace('\n\n','\n')
+ output_string = output_string.replace('\n', linesep)
+ output_string+= linesep
+ except Exception, e:
+ logging.getLogger('cone.gcfml').error('Cannot post process result: %s \nException: %s' % (string, e))
+ raise exceptions.ConeException('Cannot post process result: %s \nException: %s' % (string, e))
+
+ return output_string
+
+def write_string_to_file(string, output, enc):
+ """
+ Writes string to file
+ """
+ try:
+ outfile = os.path.abspath(output)
+
+ if not os.path.exists(os.path.dirname(outfile)):
+ os.makedirs(os.path.dirname(outfile))
+
+ fl = codecs.open(outfile, 'w', enc)
+ fl.write(string)
+ fl.close()
+
+ except Exception, e:
+ logging.getLogger('cone.gcfml').error('Cannot write Element to file (%s). Exception: %s' % (output, e))
+ raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path,sys
+from setuptools import setup, find_packages
+from genconfmlplugin import __version__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(os.path.join(ROOT_PATH,'lib'))
+
+setup(
+ name = "conegenconfmlplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "genconfml.tests.collect_suite",
+ install_requires = ['lxml>=2.2.2'],
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine Configuration Tool GenConfml plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['gcfml = genconfmlplugin.genconfmlplugin:GenconfmlImplReader']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_exceptions.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_exceptions.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from cone.public import exceptions
+
+
+# ============================================================================
+# Writer exceptions
+# ============================================================================
+
+class HcrWriterError(exceptions.ConeException):
+ pass
+
+class DuplicateRecordError(HcrWriterError):
+ pass
+
+class ValueNotInRangeError(HcrWriterError):
+ pass
+
+class TooLargeLsdDataError(HcrWriterError):
+ pass
+
+# ============================================================================
+# Reader exceptions
+# ============================================================================
+
+class HcrReaderError(exceptions.ParseError):
+ pass
+
+class InvalidHcrDataSizeError(HcrReaderError):
+ pass
+
+class InvalidHcrHeaderError(HcrReaderError):
+ pass
+
+class InvalidLsdSectionOffsetError(HcrReaderError):
+ pass
+
+class NoVersionInRepositoryError(HcrReaderError):
+ pass
+
+class NoReadOnlyAttributeInRepositoryError(HcrReaderError):
+ pass
+
+
+class InvalidRecordLsdPositionError(HcrReaderError):
+ pass
+
+class InvalidRecordValueTypeError(HcrReaderError):
+ pass
+
+
+
+# ============================================================================
+# HCRML parser exceptions
+# ============================================================================
+
+class HcrmlParserError(exceptions.ParseError):
+ pass
+
+class NoCategoryUIDInHcrmlFileError(HcrmlParserError):
+ pass
+
+class NoRefInHcrmlFileError(HcrmlParserError):
+ pass
+
+class NoTypeAttributeInSettingHcrmlFileError(HcrmlParserError):
+ pass
+
+class NoCategoryNameInHcrmlFileError(HcrmlParserError):
+ pass
+
+class NoNameAttributeInSettingHcrmlFileError(HcrmlParserError):
+ pass
+
+class NoIdAttributeInSettingHcrmlFileError(HcrmlParserError):
+ pass
+
+class NoTypeDefinedInOutPutTagError(HcrmlParserError):
+ pass
+
+class InvalidTypeDefinedInOutPutTagError(HcrmlParserError):
+ pass
+
+class NoCategoryNameDefinedInCategoryTagError(HcrmlParserError):
+ pass
+
+class NoCategoryUidDefinedInCategoryTagError(HcrmlParserError):
+ pass
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_header.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_header.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from struct import pack, unpack
+from hcrplugin.hcr_exceptions import InvalidHcrHeaderError
+
+class HcrHeader(object):
+ """
+ """
+ HEADER_FMT = '<4sHHIII12x'
+ HEADER_SIGNATURE = 'HCRf'
+ def __init__(self):
+ self.version = 0
+ self.flags = 0
+ self.nrecords = 0
+ self.lsd_offset = 0
+ self.lsd_size = 0
+
+ def loads(self, headerstr):
+ if len(headerstr) != 32:
+ raise InvalidHcrHeaderError('Invalid length of header data %r' % headerstr)
+
+ result = unpack(self.HEADER_FMT, headerstr)
+ if not result[0] == self.HEADER_SIGNATURE:
+ raise InvalidHcrHeaderError('Invalid HCR signature in %r' % headerstr)
+ self.version = result[1]
+ self.flags = result[2]
+ self.nrecords = result[3]
+ self.lsd_offset = result[4]
+ self.lsd_size = result[5]
+
+
+ def dumps(self):
+ return pack(self.HEADER_FMT, self.HEADER_SIGNATURE, self.version,
+ self.flags,
+ self.nrecords,
+ self.lsd_offset,
+ self.lsd_size)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,151 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import logging
+import __init__
+from hcrplugin.hcrrepository import HcrRecord, HcrRepository
+from struct import pack, unpack
+from hcrplugin.hcr_writer import VALUE_TYPE_MAP,VALUE_TYPES_WITH_LSD,VALUE_TYPES_UNSIGNED_INT
+from hcrplugin.hcr_header import HcrHeader
+from hcrplugin.hcr_exceptions import *
+
+
+class HcrReader(object):
+
+ def parse_repository_from_bindata(self, data):
+ """
+ @return: HcrRepository object constructed from the given binary data.
+ """
+ header_data = data[:32]
+ header = HcrHeader()
+ header.loads(header_data)
+
+ expected_len = 32 + header.nrecords * 20 + header.lsd_size
+ if len(data) < expected_len:
+ raise InvalidHcrDataSizeError("File size is %d, expected at least %d based on header" \
+ % (len(data), expected_len))
+
+ expected_lsd_offset = 32 + header.nrecords * 20
+ if header.lsd_offset != expected_lsd_offset:
+ raise InvalidLsdSectionOffsetError("LSD offset is %d, expected %d" \
+ % (header.lsd_offset, expected_lsd_offset))
+
+ records = []
+ for i in xrange(header.nrecords):
+ record_offset = 32 + i * 20
+ record_data = data[record_offset:record_offset+20]
+ record,lsd_pos = self.parse_record_from_bindata(record_data)
+ if lsd_pos != None:
+ if lsd_pos[0] > header.lsd_size or (lsd_pos[0] + lsd_pos[1]) > header.lsd_size:
+ raise InvalidRecordLsdPositionError(
+ "LSD offset of record %d (category=%d, element=%d) is %r, but LSD section size is %d" \
+ % (i, record.category_id, record.element_id, lsd_pos, header.lsd_size))
+ lsd_offset = lsd_pos[0] + header.lsd_offset
+ lsd_data = data[lsd_offset:lsd_offset+lsd_pos[1]]
+ record.value = self.parse_record_value_from_lsd_bindata(record.type,lsd_data)
+ records.append(record)
+
+ return HcrRepository(records,header.version,header.flags)
+
+ def parse_record_from_bindata(self, data):
+ """
+ @return: Tuple: (record, lsd_pos) where
+ record = HcrRecord object constructed from the given binary data.
+ lsd_pos = The position of the record's data in the LSD section in the
+ form of a tuple (offset, size), or None if the record does
+ not have any data in the LSD section.
+ """
+
+ if len(data) != 20:
+ raise HcrReaderError("Invalid record length: %d, expected 20" % len(data))
+
+ result = unpack(" 0:
+ raise DuplicateRecordError("The repository contains the following duplicate records (category ID, element ID): %r" % dup_ids)
+
+ header_data = None
+ header_size = 32
+ record_data = []
+ records_size = 0
+ lsd_data = []
+ lsd_size = 0
+ lsd_offset = None
+
+ # Generate the record and LSD section data
+ records = sorted(repository.records, key=self.get_record_setting_id)
+ for record in records:
+ lsd_pos = None
+ lsd = self.get_record_lsd_bindata(record)
+ if lsd != None:
+ # Store the position before adding the padding,
+ # because it shouldn't include the padding bytes
+ lsd_pos = (lsd_size, len(lsd))
+ lsd += self._get_padding(len(lsd))
+ lsd_data.append(lsd)
+ lsd_size += len(lsd)
+
+ rdata = self.get_record_bindata(record, lsd_pos)
+ record_data.append(rdata)
+ records_size += len(rdata)
+
+ lsd_offset = header_size + records_size
+
+ header = HcrHeader()
+ header.version = repository.version
+ header.flags = repository.flags
+ header.nrecords = len(repository.records)
+ header.lsd_offset = lsd_offset
+ header.lsd_size = lsd_size
+
+ header_data = header.dumps()
+ if len(header_data) != header_size:
+ raise RuntimeError("Internal logic error! Header size is %d and not %d as it should be!" % (len(header_data), header_size))
+
+ output = []
+ output.append(header_data)
+ output.extend(record_data)
+ output.extend(lsd_data)
+ output = ''.join(output)
+ if len(output) % 4 != 0:
+ raise RuntimeError("Internal logic error! Output size is not divisible by 4 (%d)" % (len(output)))
+
+ return output
+
+ def _get_padding(self, size, padding_char='\x00'):
+ if size % 4 == 0: amount = 0
+ else: amount = 4 - (size % 4)
+ return amount * padding_char
+
+
+ def get_record_bindata(self, record, lsd_pos=None):
+ """
+ @param lsd_pos: The position of the record's data in the Large
+ Setting Data section. Should be a tuple: (offset, size).
+ @return: The binary data to write for the given record object.
+ """
+ self._check_value_range(record)
+
+ if record.type in VALUE_TYPES_WITH_LSD:
+ RECORD_FMT = " self.LSD_MAX_SIZE_PER_RECORD:
+ msg = "Data size for value in record (category=%d, element=%d) is too large: size %d bytes, but maximum is %d bytes" \
+ % (record.category_id, record.element_id, len(result), self.LSD_MAX_SIZE_PER_RECORD)
+ raise TooLargeLsdDataError(msg)
+ return result
+
+ def _check_value_range(self, record):
+ if record.type in NUMERIC_VALUE_RANGES:
+ range = NUMERIC_VALUE_RANGES[record.type]
+
+ values = record.value
+ if not isinstance(values, list): values = [values]
+
+ for val in values:
+ if val < range[0] or val > range[1]:
+ msg = "Value in record (category=%d, element=%d) is invalid for its type ('%s'): %d is not in the range %d-%d" \
+ % (record.category_id, record.element_id, record.type, val, range[0], range[1])
+ raise ValueNotInRangeError(msg)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrml_parser.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrml_parser.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,389 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+
+
+import re
+import os
+import sys
+import logging
+import xml.parsers.expat
+import codecs
+from hcrplugin.hcr_exceptions import *
+from hcrplugin.hcrrepository import HcrRecord, HcrRepository
+from hcrplugin.hcr_writer import HcrWriter
+from hcrplugin.header_writer import *
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+
+class HcrmlImpl(plugin.ImplBase):
+ """
+
+ """
+
+ IMPL_TYPE_ID = "hcrml"
+
+ def __init__(self, resource_ref, configuration):
+ plugin.ImplBase.__init__(self, resource_ref, configuration)
+ self.logger = logging.getLogger('cone.hcrml(%s)' % resource_ref)
+ self.configuration = configuration
+ self.hcrml_file = resource_ref
+
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ @return:
+ """
+ outputfile = self.__get_output_filename()
+ if outputfile != None:
+ # Create the path to the output file
+ output_path = os.path.dirname(outputfile)
+ if output_path != '' and not os.path.exists(output_path):
+ os.makedirs(output_path)
+
+ # For output type 'hcr', write the binary repository file
+ if self.output_obj.type == 'hcr':
+ self.logger.info("Generating binary repository to '%s'" % outputfile)
+ writer = HcrWriter()
+ repo = self.output_obj.get_hcr_repository()
+ data = writer.get_repository_bindata(repo)
+ f = open(outputfile,'wb')
+ try: f.write(data)
+ finally: f.close()
+ elif self.output_obj.type == 'header':
+ self.logger.info("Generating header file to '%s'" % outputfile)
+ writer = HeaderWriter(outputfile, self.output_obj)
+ writer.write()
+ elif self.output_obj.type == None:
+ # The HCRML file contains no element, so no output should
+ # be generated
+ pass
+
+ def get_refs(self):
+ return self.refs
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ fname = self.__get_output_filename()
+ return [fname] if fname else []
+
+ def __get_output_filename(self):
+ if self.output_obj.file != None:
+ return os.path.normpath(os.path.join(self.output, self.output_obj.file))
+ else:
+ return None
+
+
+class HcrmlReader(plugin.ReaderBase):
+ NAMESPACE = 'http://www.symbianfoundation.org/xml/hcrml/1'
+ FILE_EXTENSIONS = ['hcrml']
+
+ def __init__(self, resource_ref, configuration):
+ self.configuration = configuration
+ self.hcrml_file = resource_ref
+ self.refs = []
+ self.namespaces = [self.NAMESPACE]
+ self.doc = None
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = HcrmlReader(resource_ref, configuration)
+ reader.doc = etree
+
+ impl = HcrmlImpl(resource_ref, configuration)
+ impl.output_obj = reader.read_hcrml_output()
+ impl.refs = reader.refs
+ return impl
+
+ def read_hcrml_output(self, ignore_includes=False):
+ output = Output()
+
+ # There should only be one element, so use find()
+ out_elem = self.doc.find("{%s}output" % self.namespaces[0])
+ if out_elem != None:
+ version = out_elem.get('version')
+ read_only = out_elem.get('readOnly')
+ file = out_elem.get('file')
+ type = out_elem.get('type')
+
+ if type == None or type == '':
+ raise NoTypeDefinedInOutPutTagError("Type attribute missing in hcrml file")
+
+ if type not in ('hcr', 'header'):
+ raise InvalidTypeDefinedInOutPutTagError("Type attribute invalid in hcrml file: %s" % type)
+
+ output.version = version
+ output.read_only = read_only
+ output.file = file
+ output.type = type
+
+ # An element may contain elements for including other
+ # HCRML files, so read and include categories from those
+ if not ignore_includes:
+ included_files = self.read_hcrml_includes(out_elem)
+ read_categories = self.read_categories_from_hcrml_files(included_files)
+ output.categories.extend(read_categories)
+
+
+ """ output tag is not mandatory, but there should be some categories included """
+ for cat_elem in self.doc.getiterator("{%s}category" % self.namespaces[0]):
+ category = self.read_hrcml_category(cat_elem)
+ output.categories.append(category)
+ return output
+
+ def read_hcrml_includes(self, output_elem):
+ """
+ Read all elements under an element.
+ @return: List of other HCRML files to include.
+ """
+ result = []
+
+ include_refs = []
+ for include_elem in output_elem.findall("{%s}include" % self.namespaces[0]):
+ ref = include_elem.get('ref')
+ if ref != None: include_refs.append(ref)
+
+ if include_refs:
+ # There are include refs, construct the list of files that should
+ # be included
+ all_files = self.configuration.list_resources()
+ included_files = []
+ for ref in include_refs:
+ files_by_ref = self.filter_file_list_by_include_ref(all_files, ref)
+ result.extend(files_by_ref)
+
+ # Make sure that no file is in the list more than once
+ result = list(set(result))
+ return result
+
+ def read_categories_from_hcrml_files(self, files):
+ """
+ Read all categories from the list of the given HCRML files.
+ """
+ categories = []
+
+ for file in files:
+ # Skip the current file
+ if os.path.normpath(file) == os.path.normpath(self.hcrml_file):
+ continue
+
+ # Read the element and append its categories to the result list
+ reader = HcrmlReader(file, self.configuration)
+ reader.doc = self._read_xml_doc_from_resource(file, self.configuration)
+ # Read the output element, but ignore includes, since we are
+ # currently reading from inside an include
+ output_obj = reader.read_hcrml_output(ignore_includes=True)
+ categories.extend(output_obj.categories)
+
+ return categories
+
+ def read_hrcml_category(self,cat_elem):
+ category_uid = cat_elem.get('uid')
+ if category_uid == None or category_uid == '':
+ raise NoCategoryUIDInHcrmlFileError("No category uid attribute implemented in hcrml file!")
+ name = cat_elem.get('name')
+ if name == None or name == '':
+ raise NoCategoryNameInHcrmlFileError("No category name attribute implemented in hcrml file!")
+ category = Category()
+ category.name = name
+ try:
+ category.category_uid = long(category_uid)
+ except ValueError:
+ category.category_uid = long(category_uid, 16)
+ category.xml_elem = cat_elem
+ for setting_elem in cat_elem.getiterator("{%s}setting" % self.namespaces[0]):
+ setting = self.read_hcrml_setting(setting_elem)
+ category.settings.append(setting)
+ return category
+
+
+ def read_hcrml_setting(self,setting_elem):
+
+ ref = setting_elem.get('ref')
+ if ref == None or ref == '':
+ raise NoRefInHcrmlFileError("No ref in setting tag attribute implemented in hcrml file!")
+ else:
+ self.refs.append(ref)
+ type = setting_elem.get('type')
+ if type == None or type == '':
+ raise NoTypeAttributeInSettingHcrmlFileError("No type in setting tag attribute implemented in hcrml file ref: %s" % ref )
+ name = setting_elem.get('name')
+ if name == None or name == '':
+ raise NoNameAttributeInSettingHcrmlFileError("No type in setting tag attribute implemented in hcrml file ref: %s" % ref )
+ id = setting_elem.get('id')
+ if id == None or id == '':
+ raise NoIdAttributeInSettingHcrmlFileError("No id in setting tag attribute implemented in hcrml file ref: %s" % ref )
+
+ comment = setting_elem.get('comment')
+ if comment == None:
+ comment = ''
+
+
+ setting = Setting(self.configuration)
+ setting.comment = comment
+ setting.name = name
+ setting.ref = ref
+ try:
+ setting.id = long(id)
+ except ValueError:
+ setting.id = long(id, 16)
+ setting.type = type
+ setting.xml_elem = setting_elem
+ for flag_elem in setting_elem.getiterator("{%s}flags" % self.namespaces[0]):
+ flag = self.read_hrcml_flags(setting_elem)
+ setting.flag = flag
+ return setting
+
+ def read_hrcml_flags(self,flag_elem):
+ Uninitialised = flag_elem.get('Uninitialised')
+ Modifiable = flag_elem.get('Modifiable')
+ Persistent = flag_elem.get('Persistent')
+ flag = Flag()
+ flag.Uninitialised = Uninitialised
+ flag.Modifiable = Modifiable
+ flag.Persistent = Persistent
+ return flag
+
+ def filter_file_list_by_include_ref(self, files, ref):
+ pattern = ref + '$'
+ pattern = pattern.replace('.', r'\.')
+ pattern = pattern.replace('*', '.*')
+ pattern = '(^|.*/)' + pattern
+ result = []
+ for file in files:
+ if re.match(pattern, file.replace('\\', '/')) != None:
+ result.append(file)
+ return result
+
+
+class Flag(object):
+ def __init__(self):
+ self.Uninitialised = 0
+ self.Modifiable = 0
+ self.Persistent = 0
+
+class Setting(object):
+ def __init__(self,configuration):
+ self.name = None
+ self.ref = None
+ self.type = None
+ self.id = None
+ self.flag = None
+ self.comment = ''
+ self.configuration = configuration
+
+ @property
+ def value(self):
+ dview = self.configuration.get_default_view()
+ feature = dview.get_feature(self.ref)
+ value = feature.get_value()
+
+ if self.type in (HcrRecord.VALTYPE_ARRAY_INT32, HcrRecord.VALTYPE_ARRAY_UINT32):
+ # Convert string values to numbers
+ value = map(lambda x: self.__str_to_long(x), value)
+ elif self.type == HcrRecord.VALTYPE_BIN_DATA and feature.get_type() == 'string':
+ value = self.__hex_to_bindata(value)
+ return value
+
+ def __str_to_long(self, str_value):
+ try:
+ return long(str_value)
+ except ValueError:
+ return long(str_value, 16)
+
+ def __hex_to_bindata(self, hexdata):
+ orig_hexdata = hexdata
+ hexdata = hexdata.replace(' ', '').replace('\r', '').replace('\n', '').replace('\t', '')
+ if len(hexdata) % 2 != 0:
+ raise ValueError("Failed to convert %r into binary data: String length %d (whitespace stripped) is not divisible by 2", orig_hexdata, len(hexdata))
+ for c in hexdata:
+ if c not in "0123456789abcdefABCDEF":
+ raise ValueError("Failed to convert %r into binary data: Not a valid hex string", hexdata)
+
+ temp = []
+ for i in xrange(len(hexdata) / 2):
+ start = i * 2
+ end = start + 2
+ temp.append(chr(int(hexdata[start:end], 16)))
+ return ''.join(temp)
+
+class Category(object):
+ def __init__(self):
+ self.name = None
+ self.category_uid = None
+ self.settings = []
+
+ def get_hcr_records(self):
+ """
+ Return a list of HcrRecord objects created based on this category's settings.
+ """
+ result = []
+ for setting in self.settings:
+ record = HcrRecord(setting.type, setting.value, self.category_uid, setting.id)
+ flag = setting.flag
+ if flag:
+ record.flags = 0
+ if flag.Uninitialised == '1': record.flags |= HcrRecord.FLAG_UNINITIALIZED
+ if flag.Modifiable == '1': record.flags |= HcrRecord.FLAG_MODIFIABLE
+ if flag.Persistent == '1': record.flags |= HcrRecord.FLAG_PERSISTENT
+ result.append(record)
+ return result
+
+
+class Output(object):
+ def __init__(self):
+ self.file = None
+ self.type = None
+ self.version = None
+ self.read_only = None
+ self.categories = []
+
+ def get_hcr_records(self):
+ """
+ Return a list of HcrRecord objects created based on this output object's categories.
+ """
+ result = []
+ for category in self.categories:
+ result.extend(category.get_hcr_records())
+ return result
+
+ def get_hcr_repository(self):
+ """
+ Return a HcrRepository object created based on this output.
+
+ The type of this Output object should be 'hcr', otherwise and an exception is raised.
+ """
+ if self.type != 'hcr':
+ raise RuntimeError("get_hcr_repository() called on an Output object with type '%s' (should be 'hcr')" % self.type)
+
+ return HcrRepository(self.get_hcr_records())
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrrepository.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrrepository.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,137 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import logging
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+
+class HcrRepository(object):
+ FLAG_READ_ONLY = 1
+ FLAG_NON_VOLATILE = 2
+ FLAG_BOOT_ONLY = 4
+
+ def __init__(self, records, version=1, flags=FLAG_READ_ONLY):
+ self.records = records
+ self.version = version
+ self.flags = flags
+
+ def count_records(self, category_id, element_id):
+ """
+ Return the number of records in the repository with the given
+ setting ID (category ID - element ID pair).
+ """
+ count = 0
+ for r in self.records:
+ if r.category_id == category_id and r.element_id == element_id:
+ count += 1
+ return count
+
+ def get_duplicate_record_ids(self):
+ """
+ Return a list of duplicate record IDs in the repository.
+ The list contains tuples of the form (category_id, element_id).
+ """
+ result = []
+ for r in self.records:
+ count = self.count_records(r.category_id, r.element_id)
+ record_id = (r.category_id, r.element_id)
+ if count > 1 and record_id not in result:
+ result.append(record_id)
+ return result
+
+ def __repr__(self):
+ buf = ["HcrRepository(version=%r, flags=%r, records=[" % (self.version, self.flags)]
+ if len(self.records) > 0:
+ buf.append('\n')
+ for record in sorted(self.records):
+ buf.append(" %r,\n" % record)
+ buf.append('])')
+ return ''.join(buf)
+
+ def __eq__(self, other):
+ return sorted(self.records) == sorted(other.records) \
+ and self.version == other.version \
+ and self.flags == other.flags
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+class HcrRecord(object):
+ # Record value types used in HCRML
+ VALTYPE_INT32 = 'int32'
+ VALTYPE_INT16 = 'int16'
+ VALTYPE_INT8 = 'int8'
+ VALTYPE_BOOL = 'bool'
+ VALTYPE_UINT32 = 'uint32'
+ VALTYPE_UINT16 = 'uint16'
+ VALTYPE_UINT8 = 'uint8'
+ VALTYPE_LIN_ADDR = 'linaddr'
+ VALTYPE_BIN_DATA = 'bindata'
+ VALTYPE_TEXT8 = 'text8'
+ VALTYPE_ARRAY_INT32 = 'arrayint32'
+ VALTYPE_ARRAY_UINT32 = 'arrayuint32'
+ VALTYPE_INT64 = 'int64'
+ VALTYPE_UINT64 = 'uint64'
+
+ FLAG_UNINITIALIZED = 1
+ FLAG_MODIFIABLE = 2
+ FLAG_PERSISTENT = 4
+
+
+ def __init__(self, type, value, category_id, element_id, flags=0):
+ # Check the value type
+ val_types = []
+ for name, val in self.__class__.__dict__.iteritems():
+ if name.startswith('VALTYPE_'):
+ val_types.append(val)
+ if type not in val_types:
+ raise ValueError("Invalid HCRML record type '%s'" % type)
+
+ self.type = type
+ self.value = value
+ self.category_id = category_id
+ self.element_id = element_id
+ self.flags = flags
+
+ def __repr__(self):
+ return 'HcrRecord(type=%r, value=%r, category_id=%r, element_id=%r, flags=%r)' \
+ % (self.type, self.value, self.category_id, self.element_id, self.flags)
+
+ def __lt__(self, other):
+ # Note:
+ # The < operator is implemented purely for the sake of sorting records
+ # in unit tests for comparison, the sorting is NOT the one used when
+ # actually writing the records to file
+ attrs_to_check = ['type', 'value', 'category_id', 'element_id', 'flags']
+ for attr_name in attrs_to_check:
+ x = getattr(self, attr_name)
+ y = getattr(other, attr_name)
+ if x < y: return True
+ elif x == y: continue # Equal, so need to check the next one
+ else: return False
+ return False
+
+ def __eq__(self, other):
+ attrs_to_check = ['type', 'value', 'category_id', 'element_id', 'flags']
+ for attr_name in attrs_to_check:
+ x = getattr(self, attr_name)
+ y = getattr(other, attr_name)
+ if x != y: return False
+ return True
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/header_writer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/header_writer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+
+class HeaderWriter(object):
+ def __init__(self,output_file, output_obj):
+ self.output_obj = output_obj
+ self.output_file = output_file
+
+ def write(self):
+ header_guard = os.path.basename(self.output_file).upper()
+ header_guard = header_guard.replace('/', '_').replace('\\', '_').replace('.', '_')
+ lines = [
+ "#ifndef %s" % header_guard,
+ "#define %s" % header_guard,
+ "",
+ "#include ",
+ "",
+ ]
+
+ # Sort by category UID to make testing easier
+ categories = sorted(self.output_obj.categories, key=lambda c: c.category_uid)
+ for i, category in enumerate(categories):
+ lines.append('const HCR::TCategoryUid %s = 0x%08X;' % (category.name, category.category_uid))
+ lines.append('')
+
+ # Again, sort for testability
+ settings = sorted(category.settings, key=lambda s: s.id)
+ max_name_len = max([len(s.name) for s in settings])
+ format = "const HCR::TElementId %%-%ds = 0x%%08X;" % max_name_len
+ for setting in settings:
+ if setting.comment: lines.append("// %s" % setting.comment)
+ lines.append(format % (setting.name, setting.id))
+
+ if i + 1 != len(categories):
+ lines.append('')
+ lines.append('// ' + 70 * '-')
+ lines.append('')
+
+ lines.extend([
+ "",
+ "#endif",
+ ])
+
+ f = open(self.output_file, 'wb')
+ try: f.write(os.linesep.join(lines))
+ finally: f.close()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/multi_dat/hcr.dat
Binary file configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/multi_dat/hcr.dat has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/multi_header/multi_header.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/multi_header/multi_header.h Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+#ifndef MULTI_HEADER_H
+#define MULTI_HEADER_H
+
+#include
+
+const HCR::TCategoryUid KTest1Category = 0x10001234;
+
+const HCR::TElementId KInt8Setting = 0x00000000;
+// Test setting 2
+const HCR::TElementId KUint32Setting = 0x00000001;
+const HCR::TElementId KInt32ArraySetting = 0x00000002;
+const HCR::TElementId KBinDataSetting = 0x00000003;
+
+// ----------------------------------------------------------------------
+
+const HCR::TCategoryUid KTest2Category = 0x20001234;
+
+const HCR::TElementId KLinAddrSetting = 0x00000000;
+const HCR::TElementId KInt64Setting = 0x00000001;
+const HCR::TElementId KUint32ArraySetting = 0x00000002;
+const HCR::TElementId KText8Setting = 0x00000003;
+
+// ----------------------------------------------------------------------
+
+const HCR::TCategoryUid KTest3Category = 0x30001234;
+
+const HCR::TElementId KBoolSetting = 0x00000000;
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/single_dat/hcr.dat
Binary file configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/single_dat/hcr.dat has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/single_header/test1.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/expected/single_header/test1.h Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+#ifndef TEST1_H
+#define TEST1_H
+
+#include
+
+const HCR::TCategoryUid KTest1Category = 0x10001234;
+
+const HCR::TElementId KInt8Setting = 0x00000000;
+// Test setting 2
+const HCR::TElementId KUint32Setting = 0x00000001;
+const HCR::TElementId KInt32ArraySetting = 0x00000002;
+const HCR::TElementId KBinDataSetting = 0x00000003;
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/generate_repo.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/generate_repo.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Script for generating expected data for the tests where output
+is written to a file.
+"""
+
+import os, unittest
+import __init__
+
+from testautomation.utils import hex_to_bindata
+
+from hcrplugin.hcrrepository import HcrRepository, HcrRecord
+from hcrplugin.hcr_writer import HcrWriter
+from hcrplugin import hcr_exceptions
+
+def generate_repository(file_path, records):
+ dir = os.path.dirname(file_path)
+ if dir != '' and not os.path.exists(dir):
+ os.makedirs(dir)
+
+ writer = HcrWriter()
+ repo = HcrRepository(records)
+ f = open(file_path, "wb")
+ try: f.write(writer.get_repository_bindata(repo))
+ finally: f.close()
+
+ print "Generated '%s' with %d records" % (file_path, len(records))
+
+def generate_expected_data():
+ records = []
+ category = 0x10001234
+ records.append(HcrRecord(HcrRecord.VALTYPE_INT32, 0, category, 0))
+ records.append(HcrRecord(HcrRecord.VALTYPE_INT32, 0, category, 1))
+ records.append(HcrRecord(HcrRecord.VALTYPE_INT32, 0, category, 2))
+
+ generate_repository("generated/expected/project/hcr.dat", records)
+
+ # --------------------------------------------------------------
+
+ records = []
+ category = 0x10001234
+ records.append(HcrRecord(HcrRecord.VALTYPE_INT8, 125, category, 0))
+ records.append(HcrRecord(HcrRecord.VALTYPE_UINT32, 4000000000, category, 1))
+ records.append(HcrRecord(HcrRecord.VALTYPE_ARRAY_INT32, [-1, -20, -300, -4000, -50000], category, 2))
+ records.append(HcrRecord(HcrRecord.VALTYPE_BIN_DATA, hex_to_bindata('00112233 DEADBEEF CAFE 50'), category, 3))
+
+ category = 0x20001234
+ records.append(HcrRecord(HcrRecord.VALTYPE_LIN_ADDR, 0x10203040, category, 0))
+ records.append(HcrRecord(HcrRecord.VALTYPE_INT64, 1234567890123456789, category, 1))
+ records.append(HcrRecord(HcrRecord.VALTYPE_ARRAY_UINT32, [1, 20, 300, 4000, 50000], category, 2))
+ records.append(HcrRecord(HcrRecord.VALTYPE_TEXT8, u'100\u20ac', category, 3))
+
+ category = 0x30001234
+ records.append(HcrRecord(HcrRecord.VALTYPE_BOOL, False, category, 0))
+
+ generate_repository("generated/expected/multifile_project/hcr.dat", records)
+
+if __name__ == "__main__":
+ generate_expected_data()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/confml/test1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/confml/test1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 125
+ 4000000000
+
+
+ 0
+
+ -1
+ -20
+ -300
+ -4000
+ -50000
+
+ 00112233 DEADBEEF CAFE 50
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/confml/test2.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/confml/test2.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x10203040
+ 1234567890123456789
+
+
+ 0
+
+ 1
+ 20
+ 300
+ 4000
+ 50000
+
+ 100€
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/confml/test3.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/confml/test3.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ false
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/hcr_dat.hcrml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/hcr_dat.hcrml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/multi_header.hcrml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/multi_header.hcrml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/test1.hcrml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/test1.hcrml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/test2.hcrml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/test2.hcrml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/test3.hcrml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/implml/test3.hcrml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/layer1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/multifile_project/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/project/confml/hcrexample.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/project/confml/hcrexample.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+
+
+
+ example hardware configuration repository confml
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/project/implml/example.hcrml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/project/implml/example.hcrml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/project/root.confml
Binary file configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/project/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcr_header.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcr_header.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,90 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import __init__
+
+from testautomation.utils import hex_to_bindata
+
+from hcrplugin import hcr_header
+from hcrplugin.hcr_exceptions import InvalidHcrHeaderError
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+
+class TestHCRHeader(unittest.TestCase):
+ def test_hcr_header_dumps_empty(self):
+ hcrh = hcr_header.HcrHeader()
+ self.assertEquals(len(hcrh.dumps()), 32)
+ expected_data = hex_to_bindata(
+ "48435266 0000 0000 00000000 00000000"+\
+ "00000000 000000000000000000000000")
+ self.assertEquals(hcrh.dumps(), expected_data)
+
+ def test_hcr_header_loads_empty(self):
+ hcrh = hcr_header.HcrHeader()
+ try:
+ hcrh.loads('')
+ self.fail('parsing of empty string succeeded?')
+ except InvalidHcrHeaderError:
+ pass
+
+ def test_hcr_header_loads_invalid_signature(self):
+ hcrh = hcr_header.HcrHeader()
+ try:
+ hcrh.loads(32*' ')
+ self.fail('parsing of empty string succeeded?')
+ except InvalidHcrHeaderError:
+ pass
+
+ def test_hcr_header_loads_zero(self):
+ hcrh = hcr_header.HcrHeader()
+ header_data = hex_to_bindata(
+ "48435266 0000 0000 00000000 00000000"+\
+ "00000000 000000000000000000000000")
+ hcrh.loads(header_data)
+ self.assertEquals(hcrh.version, 0)
+ self.assertEquals(hcrh.flags, 0)
+ self.assertEquals(hcrh.nrecords, 0)
+ self.assertEquals(hcrh.lsd_offset, 0)
+ self.assertEquals(hcrh.lsd_size, 0)
+
+ def test_hcr_header_dumps_some_data(self):
+ hcrh = hcr_header.HcrHeader()
+ hcrh.version = 5
+ hcrh.flags = 6
+ hcrh.nrecords = 10
+ hcrh.lsd_offset = 18
+ hcrh.lsd_size = 32
+ expected_data = hex_to_bindata(
+ "48435266 0500 0600 0A000000 12000000"+\
+ "20000000 000000000000000000000000")
+ self.assertEquals(hcrh.dumps(), expected_data)
+
+ def test_hcr_header_loads_some_data(self):
+ hcrh = hcr_header.HcrHeader()
+ header_data = hex_to_bindata(
+ "48435266 0500 0600 0A000000 12000000"+\
+ "20000000 000000000000000000000000")
+ hcrh.loads(header_data)
+ self.assertEquals(hcrh.version, 5)
+ self.assertEquals(hcrh.flags, 6)
+ self.assertEquals(hcrh.nrecords, 10)
+ self.assertEquals(hcrh.lsd_offset, 18)
+ self.assertEquals(hcrh.lsd_size, 32)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_impl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_impl.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,153 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, unittest
+import __init__
+from cone.public import plugin
+from hcrplugin.hcrml_parser import HcrmlReader
+
+def impl_from_resource(resource_ref, configuration):
+ """
+ Read a HCRML implementation from the given resource in a configuration.
+ """
+ doc_root = plugin.ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
+ return HcrmlReader.read_impl(resource_ref, configuration, doc_root)
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+NAMESPACE = 'http://www.symbianfoundation.org/xml/hcrml/1'
+
+TEST_HCRML_DATA = """
+
+
+
+
+
+
+
+
+
+
+""" % NAMESPACE
+
+HCR_DAT_HCRML_DATA = """
+
+
+
+
+
+""" % NAMESPACE
+
+NO_OUTPUT_HCRML_DATA = """
+
+
+
+
+
+
+""" % NAMESPACE
+
+class Dummy(object):
+ pass
+
+class DummyConfiguration(object):
+ RESOURCES = {
+ 'layer1/test.hcrml' : TEST_HCRML_DATA,
+ 'layer2/no_output.hcrml' : NO_OUTPUT_HCRML_DATA,
+ 'layer4/hcr_dat.hcrml' : HCR_DAT_HCRML_DATA,
+ }
+
+ def list_resources(self):
+ return sorted(self.RESOURCES.keys())
+
+ def get_resource(self, res_ref):
+ res = Dummy()
+ res.read = lambda: self.RESOURCES[res_ref]
+ res.close = lambda: None
+ return res
+
+ def get_default_view(self):
+ view = Dummy()
+ feature = Dummy()
+ feature.get_value = lambda: 0
+ view.get_feature = lambda ref: feature
+ return view
+
+class TestHcrmlImpl(unittest.TestCase):
+
+ def test_has_ref(self):
+ impl = impl_from_resource('layer1/test.hcrml', DummyConfiguration())
+ self.assertTrue(impl.has_ref(['Feature1.Setting1']))
+ self.assertTrue(impl.has_ref(['Feature1.Setting2']))
+ self.assertTrue(impl.has_ref(['Feature2.Setting1']))
+ self.assertTrue(impl.has_ref(['Feature2.Setting2']))
+ self.assertTrue(impl.has_ref(['Feature1.Setting1', 'foo.bar']))
+ self.assertTrue(impl.has_ref(['Feature1.Setting1', 'Feature1.Setting2']))
+
+ self.assertFalse(impl.has_ref([]))
+ self.assertFalse(impl.has_ref(['foo.bar']))
+ self.assertFalse(impl.has_ref(['Feature1.Setting3']))
+ self.assertFalse(impl.has_ref(['x.y.z', 'foo.bar']))
+ self.assertFalse(impl.has_ref(['Feature3.Setting1']))
+ self.assertFalse(impl.has_ref(['Feature3.Setting2']))
+
+ impl = impl_from_resource('layer2/no_output.hcrml', DummyConfiguration())
+ self.assertFalse(impl.has_ref([]))
+ self.assertFalse(impl.has_ref(['foo.bar']))
+ self.assertFalse(impl.has_ref(['Feature1.Setting1']))
+ self.assertFalse(impl.has_ref(['Feature1.Setting2']))
+ self.assertFalse(impl.has_ref(['Feature2.Setting1']))
+ self.assertFalse(impl.has_ref(['Feature2.Setting2']))
+ self.assertTrue(impl.has_ref(['Feature3.Setting1']))
+ self.assertTrue(impl.has_ref(['Feature3.Setting2']))
+
+
+ # hcr_dat.hcrml includes test.hcrml and no_output.hcrml, but it should
+ # not say that it has the setting references specified in those files
+ impl = impl_from_resource('layer4/hcr_dat.hcrml', DummyConfiguration())
+ repo = impl.output_obj.get_hcr_repository()
+ # Check that the hcr_dat.hcrml implementation does contain the
+ # records
+ self.assertEquals(len(repo.records), 6)
+ # Check that it doesn't report that it has the references
+ self.assertFalse(impl.has_ref([]))
+ self.assertFalse(impl.has_ref(['foo.bar']))
+ self.assertFalse(impl.has_ref(['Feature1.Setting1']))
+ self.assertFalse(impl.has_ref(['Feature1.Setting2']))
+ self.assertFalse(impl.has_ref(['Feature2.Setting1']))
+ self.assertFalse(impl.has_ref(['Feature2.Setting2']))
+ self.assertFalse(impl.has_ref(['Feature3.Setting1']))
+ self.assertFalse(impl.has_ref(['Feature3.Setting2']))
+
+
+ def test_list_output_files(self):
+ output_dir = 'some/test/output'
+
+ impl = impl_from_resource('layer1/test.hcrml', DummyConfiguration())
+ impl.set_output_root(output_dir)
+ self.assertEquals(
+ impl.list_output_files(),
+ [os.path.normpath(os.path.join(output_dir, 'test.h'))])
+
+ impl = impl_from_resource('layer4/hcr_dat.hcrml', DummyConfiguration())
+ impl.set_output_root(output_dir)
+ self.assertEquals(
+ impl.list_output_files(),
+ [os.path.normpath(os.path.join(output_dir, 'sys/data/hcr.dat'))])
+
+ impl = impl_from_resource('layer2/no_output.hcrml', DummyConfiguration())
+ impl.set_output_root(output_dir)
+ self.assertEquals(impl.list_output_files(), [])
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_reader.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_reader.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,249 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import __init__
+import re
+import logging
+import xml.parsers.expat
+import codecs
+from hcrplugin.hcr_exceptions import *
+from hcrplugin.hcrrepository import HcrRecord, HcrRepository
+from hcrplugin.hcrml_parser import *
+
+
+from testautomation.utils import hex_to_bindata
+
+
+from cone.public import api, exceptions
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+from cone.public import exceptions,plugin,utils,api
+
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+NAMESPACE = 'http://www.symbianfoundation.org/xml/hcrml/1'
+
+
+class DummyConfiguration(object):
+ RESOURCES = {
+ 'layer1/dummy.hcrml' : ' ' % NAMESPACE,
+ 'layer1/dummy1.hcrml' : ' ' % NAMESPACE,
+ 'layer2/dummy2.hcrml' : ' ' % NAMESPACE,
+ 'layer2/dummy3.hcrml' : ' ' % NAMESPACE,
+ 'layer3/dummy.gcfml' : '',
+ 'layer3/dummy.crml' : '',
+ 'layer4/dummy.ruleml' : '',
+ 'layer4/hcr_dat.hcrml' : ' ' % NAMESPACE,
+ }
+
+ def list_resources(self):
+ return sorted(self.RESOURCES.keys())
+
+ def get_resource(self, res_ref):
+ class DummyResource(object):
+ def __init__(self, data): self.data = data
+ def read(self): return self.data
+ def close(self): pass
+ return DummyResource(self.RESOURCES[res_ref])
+
+
+class TestHCRHeader(unittest.TestCase):
+
+ def setUp(self):
+ self.reader = HcrmlReader(None, None)
+
+ def test_read_hcrml_output(self):
+ xml = ' ' % NAMESPACE
+ self.reader.doc = ElementTree.fromstring(xml)
+ output = self.reader.read_hcrml_output()
+ self.assertEquals(output.type, 'header')
+ self.assertEquals(output.file, 'some/test/file.h')
+ self.assertEquals(output.version, None)
+ self.assertEquals(output.read_only, None)
+ self.assertEquals(output.categories, [])
+
+ def _run_test_read_invalid_hcrml_output(self, xml, expected_exception):
+ try:
+ self.reader.doc = ElementTree.fromstring(xml)
+ self.reader.read_hcrml_output()
+ self.fail("Expected exception not raised!")
+ except expected_exception:
+ pass
+
+ def test_read_invalid_hcrml_output(self):
+ xml = ' ' % NAMESPACE
+ self._run_test_read_invalid_hcrml_output(xml, NoTypeDefinedInOutPutTagError)
+
+ xml = ' ' % NAMESPACE
+ self._run_test_read_invalid_hcrml_output(xml, InvalidTypeDefinedInOutPutTagError)
+
+
+ def test_read_hcrml_output_with_include(self):
+ config = DummyConfiguration()
+ resource_ref = 'layer4/hcr_dat.hcrml'
+
+ self.reader = HcrmlReader(resource_ref, config)
+ self.reader.doc = ElementTree.fromstring(config.get_resource(resource_ref).read())
+ output = self.reader.read_hcrml_output()
+ self.assertEquals(output.type, 'hcr')
+ self.assertEquals(output.file, 'some/test/hcr.dat')
+ self.assertEquals(
+ sorted([cat.category_uid for cat in output.categories]),
+ sorted([0, 1, 2, 3]))
+
+
+ def test_read_hcrml_output_with_overlapping_includes(self):
+ config = DummyConfiguration()
+ resource_ref = 'layer4/hcr_dat.hcrml'
+
+ XML = """
+
+
+
+
+
+
+ """% NAMESPACE
+
+ self.reader = HcrmlReader(resource_ref, config)
+ self.reader.doc = ElementTree.fromstring(XML)
+ output = self.reader.read_hcrml_output()
+ self.assertEquals(output.type, 'hcr')
+ self.assertEquals(output.file, 'hcr.dat')
+ self.assertEquals(
+ sorted([cat.category_uid for cat in output.categories]),
+ sorted([0, 1, 2]))
+
+ def test_read_hcrml_category(self):
+ xml = ' '
+ etree = ElementTree.fromstring(xml)
+ category = self.reader.read_hrcml_category(etree)
+ self.assertEquals(category.name, 'KCatGPIO')
+ self.assertEquals(category.category_uid, 0x10001234)
+
+ def _run_test_read_invalid_hcrml_category(self, xml, expected_exception):
+ try:
+ etree = ElementTree.fromstring(xml)
+ setting = self.reader.read_hrcml_category(etree)
+ self.fail("Expected exception not raised!")
+ except expected_exception:
+ pass
+
+ def test_read_invalid_hcrml_category(self):
+ xml = ' '
+ self._run_test_read_invalid_hcrml_category(xml, NoCategoryUIDInHcrmlFileError)
+ xml = ' '
+ self._run_test_read_invalid_hcrml_category(xml, NoCategoryNameInHcrmlFileError)
+
+ def test_read_hcrml_setting(self):
+ xml = ' '
+ etree = ElementTree.fromstring(xml)
+ setting = self.reader.read_hcrml_setting(etree)
+ self.assertEquals(setting.ref, 'hcrexample.DebounceInterval')
+ self.assertEquals(setting.name, 'KElmGPIO_DebounceInterval')
+ self.assertEquals(setting.type, 'int32')
+ self.assertEquals(setting.id, 0)
+
+ def _run_test_read_invalid_hcrml_setting(self, xml, expected_exception):
+ try:
+ etree = ElementTree.fromstring(xml)
+ setting = self.reader.read_hcrml_setting(etree)
+ self.fail("Expected exception not raised!")
+ except expected_exception:
+ pass
+
+ def test_read_invalid_hcrml_setting(self):
+ xml = ' '
+ self._run_test_read_invalid_hcrml_setting(xml, NoRefInHcrmlFileError)
+
+ xml = ' '
+ self._run_test_read_invalid_hcrml_setting(xml, NoTypeAttributeInSettingHcrmlFileError)
+
+ xml = ' '
+ self._run_test_read_invalid_hcrml_setting(xml, NoNameAttributeInSettingHcrmlFileError)
+
+ xml = ' '
+ self._run_test_read_invalid_hcrml_setting(xml, NoIdAttributeInSettingHcrmlFileError)
+
+
+
+ def test_read_hcrml_flag(self):
+ xml = ' '
+ etree = ElementTree.fromstring(xml)
+ flag = self.reader.read_hrcml_flags(etree)
+ self.assertEquals(flag.Uninitialised, '0')
+ self.assertEquals(flag.Modifiable, '0')
+ self.assertEquals(flag.Persistent, '0')
+
+ def test_filter_file_list_by_include_ref(self):
+ lst = [
+ 'layer1/dummy.hcrml',
+ 'dummy.hcrml',
+ 'layer1/dummy1.hcrml',
+ 'layer2/dummy2.hcrml',
+ 'layer2/dummy3.hcrml',
+ 'layer3/test_dummy.hcrml',
+ 'layer3/dummy.gcfml',
+ 'layer3/dummy.crml',
+ 'layer4/hcr_dat.hcrml',
+ ]
+
+ filt = self.reader.filter_file_list_by_include_ref
+
+ self.assertEquals(sorted(filt(lst, '*.hcrml')), sorted([
+ 'dummy.hcrml',
+ 'layer1/dummy.hcrml',
+ 'layer1/dummy1.hcrml',
+ 'layer2/dummy2.hcrml',
+ 'layer2/dummy3.hcrml',
+ 'layer3/test_dummy.hcrml',
+ 'layer4/hcr_dat.hcrml',]))
+
+ self.assertEquals(sorted(filt(lst, 'dummy.hcrml')), sorted([
+ 'dummy.hcrml',
+ 'layer1/dummy.hcrml',]))
+
+ self.assertEquals(sorted(filt(lst, 'dummy*.hcrml')), sorted([
+ 'dummy.hcrml',
+ 'layer1/dummy.hcrml',
+ 'layer1/dummy1.hcrml',
+ 'layer2/dummy2.hcrml',
+ 'layer2/dummy3.hcrml',]))
+
+ self.assertEquals(sorted(filt(lst, 'layer1/*')), sorted([
+ 'layer1/dummy.hcrml',
+ 'layer1/dummy1.hcrml',]))
+
+ self.assertEquals(sorted(filt(lst, 'layer4/*')), sorted([
+ 'layer4/hcr_dat.hcrml']))
+
+ self.assertEquals(sorted(filt(lst, 'hcr_dat.hcrml')), sorted([
+ 'layer4/hcr_dat.hcrml']))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_writer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_writer.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, unittest
+import __init__
+
+from hcrplugin.hcrrepository import HcrRepository, HcrRecord
+from hcrplugin.hcr_writer import HcrWriter
+from hcrplugin import hcr_exceptions
+from cone.public import api, plugin
+from testautomation.base_testcase import BaseTestCase
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestHCRMLWrite(BaseTestCase):
+ def _run_generate_test(self, project_dir, output_dir, expected_dir, hcrml_file):
+ project_dir = os.path.join(ROOT_PATH, project_dir)
+ output_dir = os.path.join(ROOT_PATH, output_dir)
+ if expected_dir != None:
+ expected_dir = os.path.join(ROOT_PATH, expected_dir)
+
+ self.remove_if_exists(output_dir)
+
+ prj = api.Project(api.Storage.open(project_dir))
+ config = prj.get_configuration('root.confml')
+ impls = plugin.ImplFactory.get_impls_from_file(hcrml_file, config)
+ self.assertEquals(len(impls), 1)
+ impl = impls[0]
+ impl.set_output_root(output_dir)
+ impl.generate()
+
+ if expected_dir != None:
+ self.assert_dir_contents_equal(expected_dir, output_dir, ['.svn'])
+ else:
+ self.assertFalse(os.path.exists(output_dir))
+
+ def test_create_hcr_dat_from_single_hcrml_file(self):
+ self._run_generate_test(
+ project_dir = 'project',
+ output_dir = 'output/single_dat',
+ expected_dir = 'expected/single_dat',
+ hcrml_file = 'implml/example.hcrml')
+
+ def test_create_hcr_dat_from_multiple_hcrml_files(self):
+ self._run_generate_test(
+ project_dir = 'multifile_project',
+ output_dir = 'output/multi_dat',
+ expected_dir = 'expected/multi_dat',
+ hcrml_file = 'layer1/implml/hcr_dat.hcrml')
+
+ def test_create_header_from_single_hcrml_file(self):
+ self._run_generate_test(
+ project_dir = 'multifile_project',
+ output_dir = 'output/single_header',
+ expected_dir = 'expected/single_header',
+ hcrml_file = 'layer1/implml/test1.hcrml')
+
+ def test_create_header_from_multiple_hcrml_files(self):
+ self._run_generate_test(
+ project_dir = 'multifile_project',
+ output_dir = 'output/multi_header',
+ expected_dir = 'expected/multi_header',
+ hcrml_file = 'layer1/implml/multi_header.hcrml')
+
+ def test_create_nothing_from_outputless_hcrml_file(self):
+ self._run_generate_test(
+ project_dir = 'multifile_project',
+ output_dir = 'output/no_output',
+ expected_dir = None, # Check that there is no output
+ hcrml_file = 'layer1/implml/test3.hcrml')
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrrepository.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrrepository.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,145 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+
+import __init__
+
+from hcrplugin.hcrrepository import HcrRepository, HcrRecord
+from cone.public import api
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestHcrRepository(unittest.TestCase):
+ def test_repository_equality(self):
+ self.assertTrue(HcrRepository([], 1, 1) == HcrRepository([], 1, 1))
+ self.assertFalse(HcrRepository([], 1, 1) == HcrRepository([], 2, 1))
+ self.assertFalse(HcrRepository([], 1, 1) == HcrRepository([], 1, 2))
+
+ self.assertTrue(HcrRepository([], 1, 1) != HcrRepository([], 1, 2))
+
+ # Records the same, but in different order
+ r1 = HcrRepository([
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 25, 20, 62, 41),
+ HcrRecord(HcrRecord.VALTYPE_BIN_DATA, 10, 20, 31, 40),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 83, 41),
+ HcrRecord(HcrRecord.VALTYPE_UINT64, 10, 21, 30, 40)],
+ version=1, flags=1)
+ r2 = HcrRepository([
+ HcrRecord(HcrRecord.VALTYPE_UINT64, 10, 21, 30, 40),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 83, 41),
+ HcrRecord(HcrRecord.VALTYPE_BIN_DATA, 10, 20, 31, 40),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 25, 20, 62, 41),
+ ],
+ version=1, flags=1)
+ self.assertTrue(r1 == r2)
+ self.assertEquals(repr(r1), repr(r2))
+
+ r1.version = 2
+ self.assertFalse(r1 == r2)
+ r1.version = 1
+ self.assertTrue(r1 == r2)
+ r1.flags = 3
+ self.assertFalse(r1 == r2)
+ r1.flags = 1
+ self.assertTrue(r1 == r2)
+
+ r1.records.append(HcrRecord(HcrRecord.VALTYPE_LIN_ADDR, 1, 2, 3, 4))
+ self.assertFalse(r1 == r2)
+
+ def test_get_duplicate_records(self):
+ r = HcrRepository([
+ HcrRecord(HcrRecord.VALTYPE_INT8, 162, 1, 1, 93),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 172, 1, 2, 41),
+ HcrRecord(HcrRecord.VALTYPE_TEXT8, 182, 1, 3, 40),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 192, 2, 1, 41),
+ HcrRecord(HcrRecord.VALTYPE_UINT32, 202, 2, 2, 40)],
+ version=1, flags=1)
+
+ self.assertEquals(r.get_duplicate_record_ids(), [])
+
+ r.records.append(HcrRecord(HcrRecord.VALTYPE_UINT16, 212, 1, 1, 142))
+ self.assertEquals(r.get_duplicate_record_ids(), [(1, 1)])
+
+ r.records.append(HcrRecord(HcrRecord.VALTYPE_UINT64, 105, 1, 1, 142))
+ self.assertEquals(r.get_duplicate_record_ids(), [(1, 1)])
+
+ r.records.append(HcrRecord(HcrRecord.VALTYPE_UINT64, 222, 2, 2, 32))
+ self.assertEquals(r.get_duplicate_record_ids(), [(1, 1), (2, 2)])
+
+ r.records.append(HcrRecord(HcrRecord.VALTYPE_TEXT8, 232, 3, 1, 32))
+ self.assertEquals(r.get_duplicate_record_ids(), [(1, 1), (2, 2)])
+
+class TestHCRRecord(unittest.TestCase):
+
+ def test_create_record_with_valid_type(self):
+ r = HcrRecord(HcrRecord.VALTYPE_INT16, 1234, 1, 2, 3)
+ self.assertEquals(r.type, HcrRecord.VALTYPE_INT16)
+ self.assertEquals(r.value, 1234)
+ self.assertEquals(r.category_id, 1)
+ self.assertEquals(r.element_id, 2)
+ self.assertEquals(r.flags, 3)
+
+ def test_create_record_with_invalid_type(self):
+ try:
+ r = HcrRecord('foobar_type', 0, 0, 0, 0)
+ self.fail("Creating a foobar_type record succeeded!")
+ except ValueError:
+ pass
+
+ def test_record_equality(self):
+ self.assertTrue(HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93) == HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93))
+
+ self.assertFalse(HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93) == HcrRecord(HcrRecord.VALTYPE_INT16, 10, 20, 30, 93))
+ self.assertFalse(HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93) == HcrRecord(HcrRecord.VALTYPE_INT8, 2, 20, 30, 93))
+ self.assertFalse(HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93) == HcrRecord(HcrRecord.VALTYPE_INT8, 10, 2, 30, 93))
+ self.assertFalse(HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93) == HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 2, 93))
+ self.assertFalse(HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93) == HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 2))
+
+ self.assertTrue(HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93) != HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 2))
+
+ r1 = HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93)
+ r2 = HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93)
+ self.assertEquals(repr(r1), repr(r2))
+ r2.value = 12
+ self.assertNotEquals(repr(r1), repr(r2))
+
+ def test_record_sorting(self):
+ records1 = [
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 25, 20, 62, 41),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93),
+ HcrRecord(HcrRecord.VALTYPE_BIN_DATA, 10, 20, 31, 40),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 83, 41),
+ HcrRecord(HcrRecord.VALTYPE_UINT64, 10, 21, 30, 40),
+ ]
+
+ records2 = [
+ HcrRecord(HcrRecord.VALTYPE_BIN_DATA, 10, 20, 31, 40),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 25, 20, 62, 41),
+ HcrRecord(HcrRecord.VALTYPE_UINT64, 10, 21, 30, 40),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 83, 41),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93),
+ HcrRecord(HcrRecord.VALTYPE_INT8, 10, 20, 30, 93),
+ ]
+
+ self.assertNotEquals(records1, records2)
+ self.assertEquals(sorted(records1), sorted(records2))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_record.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_record.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,308 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+When editing the hex data in the test cases, this may come in handy:
+
+1. Start the Python command line interpreter
+2. Paste the following lines there:
+
+from struct import pack, unpack
+bin2hex = lambda d: ''.join("%02X" % ord(c) for c in d)
+hexpack = lambda fmt, *args: bin2hex(pack(fmt, *args))
+hex2bin = lambda h: ''.join([chr(int(h[i*2:i*2+2], 16)) for i in xrange(len(h)/2)])
+hexunpack = lambda fmt, data: unpack(fmt, hex2bin(data))
+
+Now you can get the hex representation for any format supported by
+struct.pack() easily. For example, formatting a little-endian unsigned short:
+
+>>> hexpack('>> hexunpack('>> hexpack('>> hexunpack(' 1:
+ return '"%s"' % str
+ else:
+ return str
+
+ @property
+ def tool(self):
+ return ''
+
+ @property
+ def generator(self):
+ return self._generator
+
+ @property
+ def workdir(self):
+ return self._workdir
+
+ def _get_filtered_input_files(self):
+ """
+ Get the list of InputFile objects and with ignored
+ (optional empty or invalid files) entries filtered out.
+
+ Raise InvalidInputFileException if the input file list is invalid.
+ """
+ # Get all input files
+ input_files = []
+ for input in self.generator.inputs:
+ input_files.extend(input.files)
+
+ # Check if all are empty
+ all_empty = True
+ for file in input_files:
+ if not file.is_empty():
+ all_empty = False
+ break
+ if all_empty:
+ return []
+
+ # Create the filtered list
+ result = []
+ for file in input_files:
+ if file.is_empty():
+ if file.is_optional():
+ # Optional file is empty: no error
+ pass
+ else:
+ raise InvalidInputFileException("Input file empty but not optional")
+ else:
+ if not file.is_valid():
+ raise InvalidInputFileException("Invalid input file: '%s'" % file.path)
+ else:
+ result.append(file)
+ return result
+
+class BmconvCommand(Command):
+ def __init__(self,generator):
+ super(BmconvCommand, self).__init__(generator)
+
+ def execute(self):
+ """
+ Execute the command in the current working directory
+ """
+ input_files = self._get_filtered_input_files()
+ if len(input_files) == 0: return 0
+ self.create_workdir(input_files)
+
+ if not os.path.exists(os.path.dirname(self.generator.path)):
+ os.makedirs(os.path.dirname(self.generator.path))
+
+ command = self.get_command(input_files)
+ p = subprocess.Popen(command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ # Wait for the process to return
+ out, err = [ e.splitlines() for e in p.communicate() ]
+ for outl in out:
+ if outl not in err:
+ logging.getLogger('cone.bmconv').info(outl)
+ for outl in err:
+ logging.getLogger('cone.bmconv').error(outl)
+ if p.returncode != 0:
+ logging.getLogger('cone.bmconv').error("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
+ else:
+ logging.getLogger('cone.bmconv').info("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
+ if p.returncode == 0:
+ self.clean_workdir()
+ return p.returncode
+
+ def get_command(self, input_files):
+ command = [self.tool]
+ """ Add palette file """
+ if hasattr(self._generator,'palette'):
+ command.append('/p%s' % os.path.abspath(self.generator.palette))
+
+ """ Add output file """
+ """ Add output file as compressed if needed """
+ if self.rom:
+ if self.compress:
+ command.append('/s')
+ else:
+ command.append('/r')
+ else:
+ pass
+ command.append(os.path.normpath(self.generator.path))
+
+
+ for inputfile in input_files:
+ depth = ''
+ if inputfile.depth:
+ depth = '/%s' % inputfile.depth
+ command.append('%s%s' % (depth,self.workfilename(inputfile.filename)))
+ return command
+
+ @property
+ def tool(self):
+ if hasattr(self._generator,'tool'):
+ return os.path.abspath(self._generator.tool)
+ elif hasattr(self._generator, 'tooldir'):
+ return os.path.abspath(os.path.join(self._generator.tooldir, 'bmconv'))
+ else:
+ return 'bmconv'
+
+ @property
+ def rom(self):
+ if hasattr(self._generator,'rom') and self._generator.rom.lower() == 'true':
+ return True
+ else:
+ return False
+
+ @property
+ def compress(self):
+ if hasattr(self._generator,'compress') and self._generator.compress.lower() == 'true':
+ return True
+ else:
+ return False
+
+class MifconvCommand(Command):
+ def __init__(self,generator):
+ super(MifconvCommand, self).__init__(generator)
+
+ def execute(self):
+ """
+ Execute the command in the current working directory
+ """
+ input_files = self._get_filtered_input_files()
+ if len(input_files) == 0: return 0
+ self.create_workdir(input_files)
+
+ runenv = None
+ runshell = True
+ if os.path.dirname(self.tool):
+ runenv = {}
+ runenv['path'] = os.path.dirname(self.tool)
+ runshell = True
+ if not os.path.exists(os.path.dirname(self.generator.path)):
+ os.makedirs(os.path.dirname(self.generator.path))
+
+ command = self.get_command(input_files)
+ p = subprocess.Popen(command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=runenv,
+ shell=runshell)
+
+ # Wait for the process to return
+ out, err = [ e.splitlines() for e in p.communicate() ]
+ for outl in out:
+ if outl not in err:
+ logging.getLogger('cone.mifconv').info(outl)
+ for outl in err:
+ logging.getLogger('cone.mifconv').error(outl)
+ if p.returncode != 0:
+ logging.getLogger('cone.mifconv').error("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
+ else:
+ logging.getLogger('cone.mifconv').info("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
+ if p.returncode == 0:
+ self.clean_workdir()
+ return p.returncode
+
+ def get_command(self, input_files):
+ command = [self.tool]
+
+ """ Add output file """
+ command.append(os.path.normpath(self.generator.path))
+
+ """ Add temp_path """
+ command.append("/t%s" % self.temppath)
+
+ # Add tool directory if given
+ if hasattr(self._generator,'tooldir'):
+ command.append('/S%s' % os.path.abspath(self.generator.tooldir))
+
+ """ Get input files """
+ for inputfile in input_files:
+ depth = 'c8'
+ if inputfile.depth:
+ depth = inputfile.depth
+ command.append('/%s' % depth)
+ command.append( '%s' % self.workfilename(inputfile.filename))
+ return command
+
+ @property
+ def tool(self):
+ if hasattr(self._generator,'tool'):
+ return os.path.abspath(self._generator.tool)
+ elif hasattr(self._generator, 'tooldir'):
+ return os.path.abspath(os.path.join(self._generator.tooldir, 'mifconv'))
+ else:
+ return 'mifconv'
+
+ @property
+ def temppath(self):
+ if hasattr(self._generator,'temp'):
+ return os.path.abspath(self._generator.temp)
+ else:
+ return self.workdir
+
+class CopyCommand(object):
+ def __init__(self,generator):
+ self._generator = generator
+
+ def execute(self):
+ pass
+
+ @property
+ def tool(self):
+ return 'copy'
+
+class InputFile(object):
+ def __init__(self,path,**kwargs):
+ self.configuration = None
+ self._depth = None
+ for arg in kwargs.keys():
+ if arg == 'depth':
+ # Special handling for depth ('depth' is a property that
+ # expands refs using '_depth' as the base)
+ self._depth = kwargs[arg]
+ else:
+ setattr(self, arg, kwargs[arg])
+ self._path= path
+
+ def get_input(self):
+ """
+ Get the confml ref value from configuration if the outputpath is actually a ref
+ """
+ if self._path and self.configuration is not None:
+ dview = self.configuration.get_default_view()
+ def expand(ref, index):
+ value = dview.get_feature(ref).get_original_value()
+ if value is None: return ''
+ else: return value
+ return utils.expand_delimited_tokens(self._path, expand)
+ else:
+ return self._path
+
+ def set_input(self, value): self._path = value
+
+ def del_input(self): self._path = None
+
+ @property
+ def type(self):
+ return 'file'
+
+ @property
+ def depth(self):
+ if self._depth and self.configuration:
+ dview = self.configuration.get_default_view()
+ return utils.expand_refs_by_default_view(self._depth, dview)
+ else:
+ return self._depth or ''
+
+ @property
+ def files(self):
+ """
+ Return a list of file names
+ """
+ return [self]
+
+ @property
+ def filename(self):
+ """
+ Return a the path to the layer specific filename
+ """
+ if self.configuration and self.path:
+ content = self.configuration.layered_content().flatten()
+ inputpath = self.path
+ return content.get(inputpath)
+ else:
+ return self.path
+
+ path = property(get_input, set_input, del_input, "The input 'path'.")
+
+ def is_valid(self):
+ """
+ Return whether the input file is valid (not empty
+ and exists in project content).
+ """
+ return not self.is_empty() and self.filename
+
+ def is_empty(self):
+ """
+ Return whether the input file is empty.
+ """
+ return self.path in ('', None)
+
+ def is_optional(self):
+ """
+ Return whether the input file is optional.
+ """
+ return hasattr(self, 'optional') \
+ and self.optional.lower() in ('1', 't', 'true', 'yes', 'y')
+
+ def get_refs(self):
+ return utils.extract_delimited_tokens(self._path)
+
+ def __repr__(self):
+ return "InputFile(path=%r, optional=%r)" % (self._path, self.is_optional())
+
+class InputDir(InputFile):
+ def __init__(self,path,**kwargs):
+ super(InputDir,self).__init__(path,**kwargs)
+ self._files = []
+ self._include = None
+ self._exclude = None
+
+ def get_include(self):
+ return self._include.get('pattern',[])
+
+ def set_include(self, value):
+ self._include = value
+
+ def del_include(self):
+ self._include = None
+
+ def get_exclude(self):
+ return self._exclude.get('pattern',[])
+
+ def set_exclude(self, value):
+ self._exclude = value
+
+ def del_exclude(self):
+ self._exclude = None
+
+ @property
+ def type(self):
+ return 'dir'
+
+ @property
+ def files(self):
+ """
+ Return a list of file names under this directory definition
+ """
+ if self.configuration:
+ inputlist = []
+ content = self.configuration.layered_content().flatten()
+ contentfiles = content.keys()
+
+ folderfiles = utils.resourceref.filter_resources(contentfiles, "^%s" % self.path)
+ for inputfilter in self.include:
+ folderfiles = utils.resourceref.filter_resources(folderfiles, inputfilter)
+ for excludefilter in self.exclude:
+ folderfiles = utils.resourceref.neg_filter_resources(folderfiles, excludefilter)
+ folderfiles.sort()
+ for filename in folderfiles:
+ inputlist.append(InputFile(filename, **self.__dict__))
+ return inputlist
+ else:
+ return []
+
+ include = property(get_include, set_include, del_include)
+ exclude = property(get_exclude, set_exclude, del_exclude)
+
+
+
+class ConfmlRefs(object):
+
+ ref_pattern = re.compile('^\$\{(.*)\}$')
+
+ @classmethod
+ def is_confml_ref(cls, variableref):
+ """
+
+ Returns true if the given variable ref is a confml reference
+ """
+ return cls.ref_pattern.match(variableref) != None
+
+ @classmethod
+ def get_confml_ref(cls, variableref):
+ """
+
+ Returns true if the given variable ref is a confml reference
+ """
+ matchref = cls.ref_pattern.match(variableref)
+ if matchref:
+ return matchref.group(1)
+ else:
+ return None
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/imageml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/imageml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,205 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+A plugin implementation for image selection from ConfigurationLayers.
+'''
+
+
+import re
+import os
+import sys
+import logging
+import shutil
+import xml.parsers.expat
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.public import exceptions,plugin,utils,api
+from imageplugin.generators import OutputGenerator,InputFile,InputDir,InvalidInputFileException
+
+class ImageImpl(plugin.ImplBase):
+ """
+ ContentImpl plugin finds all image resources from each layer and copies
+ them to the output correctly. It follows the Configuration project override
+ rules, so that the topmost layer files override files on the previous layers.
+ """
+
+ IMPL_TYPE_ID = "imageml"
+
+ def __init__(self,ref,configuration):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.include = {}
+ self.exclude = {}
+ self.input = ""
+ self.desc = ""
+ self.output_file = ""
+ self.logger = logging.getLogger('cone.imageml(%s)' % self.ref)
+ self.errors = False
+
+ def get_include_pattern(self):
+ include_pattern = ""
+ if self.include.has_key('pattern'):
+ include_pattern = self.include['pattern'][0]
+ return include_pattern
+
+ def get_exclude_pattern(self):
+ exclude_pattern = ""
+ if self.exclude.has_key('pattern'):
+ exclude_pattern = self.exclude['pattern'][0]
+ return exclude_pattern
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ return []
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ """
+ self.logger.info('Generating')
+ ret = True
+ for generator in self.generators:
+ self.logger.info(generator)
+ generator.subpath = self.output
+ try:
+ ret = generator.generate() and ret
+ except InvalidInputFileException, e:
+ self.logger.error(e)
+ return ret
+
+ def generate_layers(self,layers):
+ """
+ Generate the given Configuration layers.
+ """
+ return self.generate()
+
+ def get_refs(self):
+ refs = []
+ for generator in self.generators:
+ refs.extend(generator.get_refs())
+ if refs:
+ return utils.distinct_array(refs)
+ else:
+ return None
+
+
+class ImageImplReader(plugin.ReaderBase):
+ """
+ Parses a single imageml implml file
+ """
+ NAMESPACE = 'http://www.s60.com/xml/imageml/1'
+ FILE_EXTENSIONS = ['imageml']
+
+ INCLUDE_ATTR = ['pattern']
+ EXCLUDE_ATTR = ['pattern']
+ def __init__(self):
+ self.desc = None
+ self.output = None
+ self.input_dir = None
+ self.include = None
+ self.exclude = None
+ self.namespaces = [self.NAMESPACE]
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = ImageImplReader()
+ reader.desc = reader.parse_desc(etree)
+ reader.outputgenerators = reader.parse_outputs(etree)
+
+ impl = ImageImpl(resource_ref, configuration)
+ impl.desc = reader.desc
+ impl.generators = reader.outputgenerators
+ for generator in impl.generators:
+ generator.configuration = configuration
+
+ return impl
+
+ def fromstring(self, xml_as_string):
+ etree = ElementTree.fromstring(xml_as_string)
+ self.desc = self.parse_desc(etree)
+ self.outputgenerators = self.parse_outputs(etree)
+ return
+
+ def parse_desc(self,etree):
+ desc = ""
+ desc_elem = etree.find("{%s}desc" % self.namespaces[0])
+ if desc_elem != None:
+ desc = desc_elem.text
+ return desc
+
+ def parse_input_include(self,etree):
+ include_elem = etree.findall("{%s}include" % self.namespaces[0])
+ include = {}
+ for f in include_elem:
+ for key in self.INCLUDE_ATTR:
+ # Add the attribute if it is found to include dict
+ include[key] = []
+ attr = f.get(key)
+ if attr: include[key].append((attr))
+ return include
+
+ def parse_input_exclude(self,etree):
+ elem = etree.findall("{%s}exclude" % self.namespaces[0])
+ exclude = {}
+ for f in elem:
+ for key in self.EXCLUDE_ATTR:
+ # Add the attribute if it is found
+ exclude[key] = []
+ attr = f.get(key)
+ if attr: exclude[key].append((attr))
+ return exclude
+
+ def parse_inputs(self,etree):
+ inputs = etree.findall("{%s}input" % self.namespaces[0])
+ inputlist = []
+ for input_elem in inputs:
+ if input_elem.get('dir'):
+ inputdir = InputDir(input_elem.get('dir'),**input_elem.attrib)
+ inputdir.include = self.parse_input_include(input_elem)
+ inputdir.exclude = self.parse_input_exclude(input_elem)
+ inputlist.append(inputdir)
+ elif input_elem.get('file'):
+ inputlist.append(InputFile(input_elem.get('file'),**input_elem.attrib))
+ return inputlist
+
+ def parse_outputs(self,etree):
+ outputs = etree.findall("{%s}output" % self.namespaces[0])
+ outputpath = ""
+ outputgenerators = []
+ for output_elem in outputs:
+ if output_elem.get('file'):
+ outputpath = output_elem.get('file')
+ generator = OutputGenerator(outputpath,**output_elem.attrib)
+ generator.inputs = self.parse_inputs(output_elem)
+ outputgenerators.append(generator)
+ return outputgenerators
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/product.confml
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/product.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/CVC_StartupShutdownAnimations.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/CVC_StartupShutdownAnimations.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+
+
+ Startup animation. The customer specific startup element can contain either a still image or an animation with or without a customer specified tone.
+
+ Display time for still image is max 3 seconds, for animation 2.5 max seconds.
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+
+
+ Shutdown animation. The customer specific shutdown element can contain either a still image or an animation with or without a customer specified tone.
+
+ Display time for still image is max 3 seconds, for animation 2.5 max seconds.
+
+
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+
+ 3000
+
+
+
+ UI/Start-up Animation
+
+
+
+
+ 3000
+
+
+
+
+
+ UI/Shutdown Animation
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+ Z:\\resource\\apps\\startup.mif
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/depth_from_ref_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/depth_from_ref_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+ c16
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/optional_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/optional_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/startup.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/confml/startup.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,231 @@
+
+
+
+
+ Used by Starter to set the additional startup reason (lang switch, RFS, etc.)
+
+
+ Used by Starter to check whether this is the first boot. The value is set by Startup Application.
+
+
+ Used by automatic language selection to store the last automatically selected language code.
+
+
+
+
+
+ Enable/disable the SIMless Offline mode. The value must reflect the Cellular Modem implementation.
+
+
+
+
+ The welcome note image (user selection in General Settings).
+
+
+ The welcome note text (user selection in General Settings).
+
+
+ The welcome note type (user selection in General Settings).
+
+
+
+
+
+ The operator note image. Will overrule the user selection, if defined.
+
+
+ The operator note text. Will overrule the user selection, if defined.
+
+
+ Indicates the timeout for plug-in calls in milliseconds.
+
+
+ Indicates the amount of subsequent resets.
+
+
+ Indicates the maximum number of subsequent resets allowed.
+
+
+ Indicates whether to try to scale the image to better fit the screen size or just use the target size of the animation as it is.
+The value is only used if the animation format supports enabling/disabling scaling.
+0 - disable scaling
+1 - enable scaling
+
+
+ A string that defines the path to the startup tone MIDI file.
+
+
+ The volume level used when playing the startup tone. Possible values range from 0 to 10.
+
+
+ Indicates whether to try to scale the image to better fit the screen size or just use the target size of the animation as it is.
+The value is only used if the animation format supports enabling/disabling scaling.
+0 - disable scaling
+1 - enable scaling
+
+
+ A string that defines the path to the operator specific startup tone MIDI file.
+
+
+ Indicates whether to try to scale the image to better fit the screen size or just use the target size of the animation as it is.
+The value is only used if the animation format supports enabling/disabling scaling.
+0 - disable scaling
+1 - enable scaling
+
+
+
+ Starter server configuration
+
+ Used for determining if a component has been running for a long time or if it has been started just recently. This information is required when deciding whether to try to re-start the component if it dies for some reason. Key value is a time limit (in seconds) which determines whether the item has been started recently or a while ago.
+
+
+
+
+
+
+ Default date and time value to propose to user during first boot.Format is YYYYMMDD:HHMMSS. The month and day values are offset from zero.Example: 20070000:090000 - 01.01.2007 09:00 AM.
+
+
+ A string that defines the path and file name of the startup animation file. This is the first animation shown during the system start-up.The value is mandatory, and it has to be a file name and a path of a valid animation file.The animation file should be stored in a location where system applications have read access.Supported formats are SVG-T (.svg, .svgb), MIF (.mif) and GIF (.gif).The length of the startup animation should be 3 seconds.Example: Z:\\resource\\apps\\startup.svg
+
+
+ A frame delay value in microseconds for fine-tuning the startup animation.The value is only used if:a) The animation file contains an animation format, which does not contain frame delay information in it (MIF), or b) The animation file contains a still image, and no startup tone has been specified, in which case this value defines how long the image is shown.
+
+
+ A string that defines the path and file name of the operator-specific startup animation file.The operator-specific startup animation is shown after the startup animation.The value is optional. If defined, it has to be a file name and a path of a valid animation file. The animation file should be stored in a location where system applications have read access. Supported formats are SVG-T (.svg, .svgb), MIF (.mif) and GIF (.gif). The length of the operator-specific startup animation should be 3-5 seconds. Animations longer than that may cause performance problems.Example: Z:\\resource\\apps\\operatorstartup.svg
+
+
+ A frame delay value in microseconds for fine-tuning the operator-specific startup animation. The value is only used if: a) The operator-specific startup animation file contains an animation format, which does not contain frame delay information in it (MIF), or b) The operator-specific startup animation file contains a still image, and no operator-specific startup tone has been specified, in which case this value defines how long the image is shown.
+
+
+ The volume level used when playing the operator-specific startup tone.Possible values range from 0 to 10. If the ringing tone is silent, the tone is not played.
+
+
+ A string that defines the path and file name of the shutdown animation file. The shutdown animation is shown during the system shutdown. The value is optional. If defined, it has to be a file name and a path of a valid animation file. The animation file should be stored in a location where system applications have read access. Supported formats are SVG-T (.svg, .svgb), MIF (.mif) and GIF (.gif). The length of the shutdown animation should be at most 3 seconds. Example: Z:\\resource\\apps\\shutdown.svg
+
+
+ A frame delay value in microseconds for fine-tuning the shutdown animation. The value is only used if: a) The shutdown animation file contains an animation format, which does not contain frame delay information in it (MIF), or b) The shutdown animation file contains a still image, and no shutdown tone has been specified, in which case this value defines how long the image is shown.
+
+
+ A string that defines the path to the shutdown tone MIDI file.The tone is played at the same time as the shutdown animation is shown. The value is optional. The tone file should be stored in a location where system applications have read access.The shutdown tone should be at most 3 seconds long. The tone will be played to the end before continuing the shutdown.Example: Z:\\resource\\apps\\shutdown.wav
+
+
+ The volume level used when playing the shutdown tone.Possible values range from 0 to 10.If the ringing tone is silent, the tone is not played.
+
+
+
+
+ Enable / disable startup queries (city, date, time)
+
+
+
+
+ String that defines the path to first startup list extension resource file. Empty values indicates that there is no startup list extension resource file.
+
+
+ String that defines the path to second startup list extension resource file. Empty values indicates that there is no startup list extension resource file.
+
+
+
+
+
+
+
+
+ 100
+ 0
+ 0
+
+
+ 1
+
+
+ 0
+
+
+ 30000
+ 0
+ 5
+ 0
+
+ 4
+ 0
+
+ 0
+
+
+ 60
+ 20
+ 0x00000001
+
+
+
+ Z:\\resource\\apps\\startup.mbm
+ 135000
+
+ 100000
+ 4
+
+ 100000
+
+ 4
+
+
+ 1
+
+
+
+
+
+
+
+
+
+ false
+ false
+ true
+
+
+ false
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ false
+ false
+ false
+
+
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame01.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame01.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame02.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame02.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame03.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame03.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame04.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame04.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame05.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame05.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame06.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame06.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame07.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame07.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame08.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame08.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame09.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame09.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame10.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame10.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame11.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame11.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame12.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame12.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame13.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame13.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame14.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame14.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame15.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame15.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame16.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame16.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame17.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame17.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame18.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame18.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame19.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame19.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame20.bmp
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/frame20.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/wakeup_sound.mp3
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/UI/Start-up Animation/wakeup_sound.mp3 has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/svg_files/icon.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/content/svg_files/icon.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,74 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/depth_from_ref_test.imageml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/depth_from_ref_test.imageml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/optional_test.imageml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/optional_test.imageml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/startup_animation.imageml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/startup_animation.imageml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/startupmif_animation.imageml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/startupmif_animation.imageml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/root.confml
Binary file configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_generators.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_generators.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,143 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import __init__
+
+from imageplugin import imageml,generators
+from cone.public import api, exceptions, plugin
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+def impl_from_resource(resource_ref, configuration):
+ impls = plugin.ImplFactory.get_impls_from_file(resource_ref, configuration)
+ assert len(impls) == 1
+ return impls[0]
+
+class TestGenerator(unittest.TestCase):
+ def test_create_generator_with_output(self):
+ gen = generators.OutputGenerator('foo/bar')
+ self.assertEquals(gen.outputpath,'foo/bar')
+ gen.outputpath = 'foo/bar/test.confml'
+ self.assertEquals(gen.outputpath,'foo/bar/test.confml')
+ del gen.outputpath
+ self.assertEquals(gen.outputpath,None)
+
+
+ def test_generator_subpath_and_path(self):
+ gen = generators.OutputGenerator('foo/bar.mbm')
+ self.assertEquals(gen.subpath, '')
+ gen.subpath = 'test/foo'
+ self.assertEquals(gen.subpath, 'test/foo')
+ self.assertEquals(gen.path, 'test/foo/foo/bar.mbm')
+ self.assertTrue(isinstance(gen.get_command(), generators.BmconvCommand))
+ gen.outputpath = 'bar/test.mif'
+ self.assertTrue(isinstance(gen.get_command(), generators.MifconvCommand))
+ gen.outputpath = 'bar/test.gif'
+ self.assertTrue(isinstance(gen.get_command(), generators.CopyCommand))
+
+
+class TestInputFile(unittest.TestCase):
+ def test_create_inputfile(self):
+ input = generators.InputFile('foo/bar.bmb')
+ self.assertEquals(input.path,'foo/bar.bmb')
+ self.assertEquals(input.files[0].filename, 'foo/bar.bmb')
+ input.path = 'foo/bar/test.confml'
+ self.assertEquals(input.path,'foo/bar/test.confml')
+ del input.path
+ self.assertEquals(input.path,None)
+
+
+ def test_create_inputfile_with_args(self):
+ input = generators.InputFile('foo/bar.bmb',depth="c8",test="juu")
+ self.assertEquals(input.path,'foo/bar.bmb')
+ self.assertEquals(input.depth,'c8')
+ self.assertEquals(input.test,'juu')
+
+class TestInputDir(unittest.TestCase):
+ def test_create_inputdir(self):
+ dir = generators.InputDir('foo/bar', dir='foo/bar',depth="c8")
+ self.assertEquals(dir.path,'foo/bar')
+ self.assertEquals(dir.depth,'c8')
+ self.assertEquals(dir.files, [])
+
+ def test_create_inputdir_and_get_files(self):
+ dir = generators.InputDir('imageproject/variant/content/UI/Start-up Animation')
+ dir.include = {'pattern' : 'bmp$'}
+ self.assertEquals(dir.files, [])
+
+class TestGeneratorFromProject(unittest.TestCase):
+ def test_create_generator_from_project(self):
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject")))
+ config = prj.get_configuration('product.confml')
+ impl = impl_from_resource('variant/implml/startup_animation.imageml', config)
+ self.assertEquals(impl.generators[0].outputpath, 'startup.mbm')
+ self.assertEquals(impl.generators[0].configuration, config)
+ self.assertEquals(impl.generators[0].palette, '../bin/ThirdPartyBitmap.pal')
+ self.assertEquals(impl.generators[0].inputs[0].configuration, config)
+ self.assertEquals(impl.generators[0].inputs[0].path, 'UI/Start-up Animation')
+ self.assertEquals(impl.generators[0].inputs[0].type, 'dir')
+ self.assertEquals(impl.generators[1].outputpath, 'nocompress.mbm')
+ self.assertEquals(impl.generators[1].get_command().compress, False)
+ self.assertEquals(impl.generators[1].inputs[0].configuration, config)
+ self.assertEquals(impl.generators[1].inputs[0].path, 'UI/Start-up Animation')
+ self.assertEquals(impl.generators[1].inputs[0].type, 'dir')
+ self.assertEquals(len(impl.generators[1].inputs[0].files),20)
+ self.assertEquals(impl.generators[1].inputs[0].files[0].filename,'variant/content/UI/Start-up Animation/frame01.bmp')
+ self.assertEquals(impl.generators[1].inputs[0].files[0].path,'UI/Start-up Animation/frame01.bmp')
+ self.assertEquals(impl.generators[1].inputs[0].files[0].depth,'c8')
+ self.assertEquals(impl.generators[1].inputs[0].files[19].filename,'variant/content/UI/Start-up Animation/frame20.bmp')
+ self.assertEquals(impl.generators[1].inputs[0].files[19].depth,'c8')
+
+ def test_create_generator_with_configurable_depth_from_project(self):
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject")))
+ config = prj.get_configuration('product.confml')
+ impl = impl_from_resource('variant/implml/depth_from_ref_test.imageml', config)
+ self.assertEquals(impl.generators[0].inputs[0].depth, 'c16')
+ self.assertEquals(impl.generators[1].inputs[0].depth, 'c16')
+
+ # Assert the the depth is actually used in the command
+ command_obj = impl.generators[0].get_command()
+ cmd = command_obj.get_command(command_obj._get_filtered_input_files())
+ self.assertEquals(len(cmd), 4)
+ self.assertEquals(cmd[3], r'/c16conversion_workdir\frame01.bmp')
+
+ command_obj = impl.generators[1].get_command()
+ cmd = command_obj.get_command(command_obj._get_filtered_input_files())
+ self.assertEquals(len(cmd), 5)
+ self.assertEquals(cmd[3], '/c16')
+ self.assertEquals(cmd[4], r'conversion_workdir\icon.svg')
+
+ def test_create_generator_with_invalid_output(self):
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject")))
+ config = prj.get_configuration('product.confml')
+ impl = impl_from_resource('variant/implml/startup_animation.imageml', config)
+ impl.generators[0].outputpath = '${KCRUidStartup.StartupOperatorAnimationPath}'
+ try:
+ self.assertEquals(impl.generators[0].outputpath, '${KCRUidStartup.StartupOperatorAnimationPath}')
+ self.fail("Output path value should be none")
+ except exceptions.NotFound:
+ pass
+
+ try:
+ self.assertEquals(impl.generators[0].outputpath, '${KCRUidStartup.foobar}')
+ self.fail("Output path ref is invalid!")
+ except exceptions.NotFound:
+ pass
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_parseimpl.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_parseimpl.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,174 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil
+import sys
+import __init__
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+from imageplugin import imageml
+
+
+imageml_string = \
+'''
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+'''
+
+imageml_with_refs = \
+'''
+
+
+
+
+
+
+
+
+
+
+
+'''
+input_dir= \
+'''
+
+
+
+
+
+
+
+
+'''
+input_files = \
+'''
+
+
+
+
+
+'''
+
+class TestImagemlParseimpl(unittest.TestCase):
+
+ def test_parse_output(self):
+ etree = ElementTree.fromstring(imageml_string)
+ reader = imageml.ImageImplReader()
+ outgens = reader.parse_outputs(etree)
+ self.assertEquals(outgens[0].outputpath,'startup.mbm')
+
+ def test_parse_input_include(self):
+ etree = ElementTree.fromstring(input_dir)
+ input = etree.find("{%s}input" % 'http://www.s60.com/xml/imageml/1')
+ reader = imageml.ImageImplReader()
+ include = reader.parse_input_include(input)
+ self.assertEquals(include,{'pattern': ['bmb$']})
+
+ def test_parse_input_exclude(self):
+ etree = ElementTree.fromstring(input_dir)
+ input = etree.find("{%s}input" % 'http://www.s60.com/xml/imageml/1')
+ reader = imageml.ImageImplReader()
+ include = reader.parse_input_exclude(input)
+ self.assertEquals(include,{'pattern': ['.svn']})
+
+ def test_parse_inputs_with_dir(self):
+ etree = ElementTree.fromstring(input_dir)
+ reader = imageml.ImageImplReader()
+ inputs = reader.parse_inputs(etree)
+ self.assertEquals(inputs[0].path,'UI/Start-up Animation')
+ self.assertEquals(inputs[0].type,'dir')
+ self.assertEquals(inputs[0].include, ['bmb$'])
+ self.assertEquals(inputs[0].exclude, ['.svn'])
+ self.assertEquals(inputs[0].depth,'8')
+ self.assertEquals(inputs[0].test,'foo')
+ self.assertEquals(inputs[1].path,'UI/Start-up Animation/masks')
+ self.assertEquals(inputs[1].depth,'2')
+
+ def test_parse_inputs_with_files(self):
+ etree = ElementTree.fromstring(input_files)
+ reader = imageml.ImageImplReader()
+ inputs = reader.parse_inputs(etree)
+ self.assertEquals(inputs[0].path,'UI/graphics/icon1.bmb')
+ self.assertEquals(inputs[0].depth,'8')
+ self.assertEquals(inputs[1].path,'UI/graphics/icon2.bmb')
+ self.assertEquals(inputs[1].depth,'8')
+ self.assertEquals(inputs[2].path,'UI/graphics/icon3.bmb')
+ self.assertEquals(inputs[2].depth,'8')
+ self.assertEquals(inputs[3].path,'UI/graphics/icon4.bmb')
+ self.assertEquals(inputs[3].depth,'8')
+
+ def test_parse_outputs(self):
+ etree = ElementTree.fromstring(imageml_string)
+ reader = imageml.ImageImplReader()
+ outputs = reader.parse_outputs(etree)
+ self.assertEquals(outputs[0].outputpath,'startup.mbm')
+ self.assertEquals(outputs[0].inputs[0].path,'UI/Start-up Animation')
+ self.assertEquals(outputs[0].inputs[0].type,'dir')
+ self.assertEquals(outputs[0].inputs[0].include,['bmb$'])
+ self.assertEquals(outputs[0].inputs[0].exclude,['.svn'])
+ self.assertEquals(outputs[1].outputpath,'shutdown.mbm')
+ self.assertEquals(outputs[1].inputs[0].type,'file')
+ self.assertEquals(outputs[1].inputs[0].path,'UI/graphics/icon1.bmb')
+ self.assertEquals(outputs[1].inputs[1].type,'file')
+ self.assertEquals(outputs[1].inputs[1].path,'UI/graphics/icon2.bmb')
+ self.assertEquals(outputs[1].inputs[2].type,'file')
+ self.assertEquals(outputs[1].inputs[2].path,'UI/graphics/icon3.bmb')
+ self.assertEquals(outputs[1].inputs[3].type,'file')
+ self.assertEquals(outputs[1].inputs[3].path,'UI/graphics/icon4.bmb')
+
+ def test_parse_from_string(self):
+ reader = imageml.ImageImplReader()
+ reader.fromstring(imageml_string)
+ self.assertEquals(reader.desc,'')
+ self.assertEquals(reader.outputgenerators[0].outputpath,'startup.mbm')
+ self.assertEquals(reader.outputgenerators[0].inputs[0].path,'UI/Start-up Animation')
+ self.assertEquals(reader.outputgenerators[0].inputs[0].type,'dir')
+ self.assertEquals(reader.outputgenerators[0].inputs[0].include,['bmb$'])
+ self.assertEquals(reader.outputgenerators[0].inputs[0].exclude,['.svn'])
+
+ def test_parse_from_string_with_refs(self):
+ reader = imageml.ImageImplReader()
+ reader.fromstring(imageml_with_refs)
+ self.assertEquals(reader.outputgenerators[0]._outputpath,'${features.outputref}')
+ self.assertEquals(reader.outputgenerators[0].inputs[0]._path,'${features.inputref}')
+ self.assertEquals(reader.outputgenerators[0].inputs[0].type,'dir')
+ self.assertEquals(reader.outputgenerators[0].inputs[0].include,['${features.inputfilter}'])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os, shutil, re
+import sys
+import logging
+import shutil
+import __init__
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from imageplugin import imageml
+from testautomation.base_testcase import BaseTestCase
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata = os.path.join(ROOT_PATH,'imageproject')
+
+class TestGeneratorFromProject(BaseTestCase):
+ def test_create_generator_from_project_and_generate_all(self):
+ orig_workdir = os.getcwd()
+ os.chdir(ROOT_PATH)
+ try:
+ output = os.path.join(ROOT_PATH, "temp/output_all")
+ self.recreate_dir(output)
+
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject")))
+ config = prj.get_configuration('product.confml')
+ implcontainer = plugin.get_impl_set(config, 'imageml$')
+ self.assertEquals(len(implcontainer), 4)
+ implcontainer.output = output
+ implcontainer.generate()
+
+ def check_gen(p):
+ self.assert_exists_and_contains_something(os.path.join(output, p))
+ def check_not_gen(p):
+ self.assertFalse(os.path.exists(os.path.join(output, p)), "'%s' exists when it should not!" % p)
+
+ try:
+ check_gen('startup.mbm')
+ check_gen('startup_mif.mif')
+
+ check_not_gen('optional1_mbm.mbm')
+ check_gen('optional2_mbm.mbm')
+ check_not_gen('optional3_mbm.mbm')
+ check_not_gen('optional4_mbm.mbm')
+
+ check_not_gen('optional1_mif.mif')
+ check_gen('optional2_mif.mif')
+ check_not_gen('optional3_mif.mif')
+ check_not_gen('optional4_mif.mif')
+
+ check_gen('resource/apps/startup.mif')
+
+ check_gen('depth_from_ref_test_mbm.mbm')
+ check_gen('depth_from_ref_test_mif.mif')
+ except AssertionError:
+ if ' ' in ROOT_PATH:
+ self.fail("Known bug (#177)")
+ else:
+ raise
+ finally:
+ os.chdir(orig_workdir)
+
+ def _get_impl(self, filename):
+ prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH, "imageproject")))
+ config = prj.get_configuration('product.confml')
+ implcontainer = plugin.get_impl_set(config, re.escape(filename) + '$')
+ self.assertEquals(len(implcontainer), 1)
+ return iter(implcontainer).next()
+
+
+ def test_get_refs(self):
+ impl = self._get_impl('startupmif_animation.imageml')
+ self.assertEquals(impl.get_refs(), None)
+ self.assertEquals(impl.has_ref('Foo.Bar'), None)
+
+ impl = self._get_impl('optional_test.imageml')
+ self.assertEquals(impl.get_refs(), ['OptionalTest.EmptyString',
+ 'OptionalTest.EmptyString2'])
+ self.assertEquals(impl.has_ref('OptionalTest.EmptyString'), True)
+ self.assertEquals(impl.has_ref('Foo.Foo'), False)
+
+ impl = self._get_impl('startup_animation.imageml')
+ self.assertEquals(impl.get_refs(), ['CVC_StartupAnimationSequence.CVC_StartupFrameLocation.localPath'])
+ self.assertEquals(impl.has_ref('CVC_StartupAnimationSequence.CVC_StartupFrameLocation.localPath'), True)
+ self.assertEquals(impl.has_ref('Foo.Foo'), False)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeImagePlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from imageplugin import __version__
+
+setup(
+ name = "coneimageplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "imageplugin.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine Content copier plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['imageml = imageplugin.imageml:ImageImplReader']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/.project
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/.project Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+
+
+ ConeProjectConverterPlugin
+
+
+
+
+
+ org.python.pydev.PyDevBuilder
+
+
+
+
+
+ org.python.pydev.pythonNature
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/.pydevproject
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/.pydevproject Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+python 2.5
+Default
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
+
+
+import pkg_resources
+import sys,os
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/convertproject.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/convertproject.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,665 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+'''
+Convert project ConE plugin
+'''
+
+import re
+import os
+import sys
+import logging
+import xml.parsers.expat
+import shutil
+import fnmatch
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import __init__
+
+from cone.storage import filestorage
+from cone.public import exceptions,plugin,utils,api
+
+class ConvertProjectImpl(plugin.ImplBase):
+ """
+ Class to implements ConE plugin that convert old configuration to
+ configuration project. Some extra functions supported in the top
+ of normal file copying functions. For example creation of layer and
+ configuration root files automatically.
+ """
+
+ IMPL_TYPE_ID = "convertprojectml"
+
+
+ def __init__(self,ref,configuration):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.desc = ""
+ self.logger = logging.getLogger('cone.convertprojectml(%s)' % self.ref)
+ self.errors = False
+
+ #Internal plugin data
+ self.project_data = {}
+ self.layers = []
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ """
+
+ #Generating content
+ fullOutputPath = self.output
+ if self.project_data.has_key("path"):
+ targetPath = utils.resourceref.norm(self.project_data["path"])
+ if targetPath and targetPath != "":
+ fullOutputPath = os.path.join(fullOutputPath, targetPath)
+
+ fs = filestorage.FileStorage(fullOutputPath, "w")
+ newProject = api.Project(fs)
+ for layer in self.layers:
+ layer.generate(newProject, self.configuration.get_storage().get_path())
+ newProject.close()
+
+ #Opening project again to validate the content and remove illegal includes.
+ if self.project_data.has_key("validate") and self.project_data["validate"] != "false":
+ fs = filestorage.FileStorage(fullOutputPath, "w")
+ validateProject = api.Project(fs)
+ for conf in validateProject.list_configurations():
+ validateProject.get_configuration(conf).list_all_configurations()
+ validateProject.close()
+
+ return
+
+ def generate_layers(self,layers):
+ """
+ Generate the given Configuration layers.
+ """
+ self.logger.info('Generating layers %s' % layers)
+ self.generate()
+
+ return
+
+ def has_ref(self,ref):
+ """
+ @returns True if the implementation uses the given ref as input value.
+ Otherwise return False.
+ """
+
+ return None
+
+#=================================================================
+class ConvertProjectLayer(object):
+ """
+ Object presenting layer in convertprojectml file.
+ """
+
+ def __init__(self, path):
+ if path != None:
+ self.path = path
+ else:
+ self.path = ""
+ self.folders = []
+ self.files = []
+
+ def __str__(self):
+ retStr = ""
+ retStr += "\nPath: %s\n" % self.path
+ retStr +="Folders:\n"
+ for folder in self.folders:
+ retStr += folder.__str__()
+ retStr +="Files:\n"
+ for file in self.files:
+ retStr += file.__str__()
+ return retStr
+
+ def generate(self, project, old_structure_root):
+ """
+ Function to handle generation to one folder.
+ """
+
+ #Create layer folder.
+ project.get_storage().create_folder(utils.resourceref.norm(self.path))
+ #print "Created Layer:", utils.resourceref.norm(self.path)
+
+ for folder in self.folders:
+ folder.generate(project, old_structure_root)
+
+ for f in self.files:
+ f.generate(project, old_structure_root)
+
+ return
+
+ def addFolder(self, folder):
+ self.folders.append(folder)
+
+ def addFile(self, file):
+ self.files.append(file)
+
+ def getProjectPath(self):
+ return self.path
+
+
+class ConvertProjectFolder(object):
+ """
+ Object presenting folder in convertprojectml file.
+ """
+
+ def __init__(self, path, parent=None):
+ if path != None:
+ self.path = path
+ else:
+ self.path = ""
+ self.filters = []
+ self.parent = parent
+
+ def __str__(self):
+ retStr = ""
+ retStr += "\tPath: %s\n" % self.path
+ retStr +="\tFilters:\n"
+ for filter in self.filters:
+ retStr += filter.__str__()
+ return retStr
+
+ def generate(self, project, old_structure_root):
+
+ #Adding new folder to project.
+ project.get_storage().create_folder(utils.resourceref.norm(self.getProjectPath()))
+ #print "Created folder:", utils.resourceref.norm(self.getProjectPath())
+
+ for filter in self.filters:
+ filter.generate(project, old_structure_root, "folder")
+ return
+
+ def addFilter(self, filter):
+ self.filters.append(filter)
+
+ def getProjectPath(self):
+ return os.path.join(self.parent.getProjectPath(), self.path)
+
+class ConvertProjectFile(object):
+ """
+ Object presenting file in convertprojectml file.
+ """
+
+ def __init__(self, path, type, parent=None):
+ if path != None:
+ self.path = path
+ else:
+ self.path = ""
+ if type != None:
+ self.type = type
+ else:
+ self.type = ""
+
+ self.filters = []
+ self.parent = parent
+ self.meta = []
+ self.desc = ""
+
+ def __str__(self):
+ retStr = ""
+ retStr += "\tPath: %s\n" % self.path
+ retStr += "\tType: %s\n" % self.type
+ retStr +="\tFilters:\n"
+ for filter in self.filters:
+ retStr += filter.__str__()
+ return retStr
+
+ def generate(self, project, old_structure_root):
+ for filter in self.filters:
+ filter.generate(project, old_structure_root, self.type)
+
+ if self.type == "configuration_root":
+ #Adding metadata
+ config = project.get_configuration(utils.resourceref.norm(self.path))
+ if self.meta:
+ if not config.meta:
+ config.meta = []
+ for meta in self.meta:
+ config.meta.add(meta[0], meta[1], meta[2], meta[3])
+ if self.desc:
+ config.desc = self.desc
+
+ config.save()
+ return
+
+ def addFilter(self, filter):
+ self.filters.append(filter)
+
+ def addMeta(self, meta):
+ self.meta = meta
+
+ def addDescription(self, desc):
+ self.desc = desc
+
+ def getProjectPath(self):
+ return os.path.join(self.parent.getProjectPath(), self.path)
+
+class ConvertProjectFilter(object):
+ """
+ Object presenting filter in convertprojectml file.
+ """
+
+ def __init__(self, action, data, parent=None, remove_includes = "false", recursive = "false"):
+ self.action = action
+ self.data = data
+ self.parent = parent
+ if remove_includes:
+ self.remove_includes = remove_includes
+ else:
+ self.remove_includes = "false"
+ if recursive:
+ self.recursive = recursive
+ else:
+ self.recursive = "false"
+
+ def __str__(self):
+ retStr = ""
+ retStr += "\t\tAction: %s\n" % self.action
+ retStr += "\t\tData: %s\n" % self.data
+ return retStr
+
+ def generate(self, project, old_structure_root, type="none"):
+ """
+ @param project: New configuration project
+ @type project:
+ @param old_structure_root: Path to old projects root.
+ @type old_structure_root:
+
+ """
+
+ if type == "" or type == "folder":
+ self.handleAddRemove(project, old_structure_root)
+ elif type == "layer_root":
+ self.handleLayerRoot(project)
+ elif type == "configuration_root":
+ self.handleConfigurationRoot(project)
+ else:
+ #raise exceptions.NotSupportedException("Type: %s not supported as file type" % repr(type))
+ pass
+ return
+
+ def handleAddRemove(self, project, old_structure_root):
+ """
+ """
+
+ pathPart, wildCardPart = self.separatePathAndWildcard(self.data)
+ filesToProcess = []
+ if wildCardPart == "":
+ #No wildcards found.
+ if self.recursive == "false":
+ source = os.path.join(old_structure_root, pathPart)
+ targetDir = self.resolveTargetDir(project, source)
+ filesToProcess.append({"source": source, "targetDir": targetDir})
+ else:
+ #recursive search for directory entries.
+ directoryPath = os.path.join(old_structure_root, pathPart)
+ if os.path.isdir(directoryPath):
+ for root, dirs, files in os.walk(directoryPath):
+ for f in files:
+ #Handling files.
+ source = os.path.join(root, f)
+ targetDir = self.resolveTargetDir(project, source)
+ filesToProcess.append({"source": source, "targetDir": targetDir})
+
+ for d in dirs:
+ #Handling directories to get empty folders included also.
+ source = os.path.join(root, d)
+ targetDir = self.resolveTargetDir(project, source)
+ filesToProcess.append({"source": source, "targetDir": targetDir})
+
+ else:
+ #Need to handle wildcard part
+ filesToProcess = self.getFilesByWildcard(os.path.join(old_structure_root, pathPart)\
+ ,wildCardPart, project)
+
+ for f in filesToProcess:
+ source = f["source"]
+ targetDir = f["targetDir"]
+
+ if source.lower().find(".svn") != -1:
+ #Ignoring svn files
+ continue
+
+ if os.path.isfile(source):
+ #targetDir = self.resolveTargetDir(project, f)
+ if self.action == "add":
+ if not os.path.exists(targetDir):
+ os.makedirs(targetDir)
+ shutil.copy2(source, targetDir)
+ elif self.action == "remove":
+ targetFile = os.path.join(targetDir, os.path.split(source)[1])
+ os.remove(targetFile)
+ elif os.path.isdir(source):
+ folderToCreate = os.path.join(targetDir, os.path.split(source)[1])
+ if not os.path.isdir(folderToCreate):
+ os.makedirs(folderToCreate)
+
+ def resolveTargetDir(self, project, filepath):
+ """
+ """
+ if self.recursive == "false":
+ return os.path.join(project.get_storage().get_path(), self.getProjectPath())
+ else:
+ retPath = os.path.join(project.get_storage().get_path(), self.getProjectPath())
+ startFound = 0
+
+ for item in os.path.normpath(filepath).split("\\"):
+ if self.data.find(item) != -1:
+ startFound = 1
+ if startFound and self.data.find(item) == -1:
+ retPath = os.path.join(retPath, item)
+ return os.path.split(retPath)[0]
+
+
+ def handleLayerRoot(self, project):
+ """
+ """
+
+ pathPart, wildCardPart = self.separatePathAndWildcard(self.data)
+ filesToProcess = []
+
+ if wildCardPart == "":
+ #No wildcards found. Checking still if path has folder and file elements
+
+ folderPath, filePart = os.path.split(pathPart)
+ if folderPath == "":
+ #filename only
+ pathPart = ""
+ else:
+ #file and folder
+ pathPart = folderPath
+
+ source = os.path.join(project.get_storage().get_path(), self.getProjectPath(), pathPart, filePart)
+ filesToProcess.append({"source": source, "targetDir": None})
+
+ else:
+ #Need to handle wildcard part
+ fullSearchPath = os.path.join(project.get_storage().get_path(), self.getProjectPath(), pathPart)
+ filesToProcess = self.getFilesByWildcard(fullSearchPath, wildCardPart, project)
+
+ #Creating rootfile.
+ rootFilePath = os.path.join(self.getProjectPath(), self.parent.path)
+ config = project.create_configuration(utils.resourceref.norm(rootFilePath))
+
+ #Adding defined includes.
+ for f in filesToProcess:
+ source = f["source"]
+ #Getting path in configuration project and adding it as include.
+ filePath = utils.resourceref.norm(os.path.join(pathPart, os.path.split(source)[1]))
+ config.include_configuration(filePath)
+ if self.remove_includes == "true":
+ self.removeIncludes(config.get_configuration(filePath))
+ config.save()
+
+ def removeIncludes(self, config):
+ """
+ @param config: Configuration object that is processed
+
+ @return: None
+ """
+
+ #Getting all configurations from included configuration.
+ configList = config.list_configurations()
+ for item in configList:
+ config.remove_configuration(utils.resourceref.norm(item))
+
+ config.save()
+
+
+ def handleConfigurationRoot(self, project):
+ """
+ """
+ #Always in the root of the project
+ configname = utils.resourceref.norm(self.parent.path)
+ if configname in project.list_configurations():
+ config = project.get_configuration(configname)
+ else:
+ config = project.create_configuration(utils.resourceref.norm(self.parent.path))
+ config.include_configuration(utils.resourceref.norm(self.data))
+ config.save()
+
+
+ def getProjectPath(self):
+ if isinstance(self.parent, ConvertProjectFile):
+ #print "FILE", self.parent.parent.getProjectPath()
+ return self.parent.parent.getProjectPath()
+ else:
+ #print "other"
+ return self.parent.getProjectPath()
+
+
+ def getFilesByWildcard(self, folder, wildcard, project):
+ """
+ @param folder: folder where matching is made
+ @type folder: string
+ @param wildcard: wildcard pattern
+ @type wildcard: string
+ """
+
+ #Array of files and folders matching with the wildcard.
+ retArray = []
+ if os.path.isdir(folder):
+ for root, dirs, files in os.walk(folder):
+ if self.recursive == "false" and os.path.normpath(root) != os.path.normpath(folder):
+ #No recursive search used and therefore only topmost directory is handled.
+ continue
+ else:
+ for f in files:
+ if fnmatch.fnmatch(os.path.join(root, f), wildcard):
+ source = os.path.join(root, f)
+ targetDir = self.resolveTargetDir(project, source)
+ retArray.append({"source": source, "targetDir": targetDir})
+
+ for d in dirs:
+ if fnmatch.fnmatch(os.path.join(root, d), wildcard):
+ source = os.path.join(root, d)
+ targetDir = self.resolveTargetDir(project, source)
+ retArray.append({"source": source, "targetDir": targetDir})
+
+ return retArray
+
+ def separatePathAndWildcard(self, data):
+ """
+ @param data: data from XML that may contain path and wildcard parts
+ @type data: string
+
+ @return: Path and wildcard parts separately.
+ """
+ pathPart = ""
+ wildCardPart = ""
+
+ if data.find("*") == -1:
+ #Only supported wildcard is currently *
+ pathPart = data
+ wildCardPart =""
+ else:
+ #Some wildcards found. Wildcards are supported only in the last segment.
+ pathPart, wildCardPart = os.path.split(data)
+
+ return pathPart, wildCardPart
+
+
+#=================================================================
+
+class ConvertProjectReader(plugin.ReaderBase):
+ """
+ Parses a single convertprojectml file
+ """
+
+ NAMESPACE = 'http://www.s60.com/xml/convertprojectml/1'
+ FILE_EXTENSIONS = ['convertprojectml']
+
+ def __init__(self):
+ self.desc = None
+ self.output_dir = None
+ self.input_dir = None
+ self.namespaces = [self.NAMESPACE]
+ self.project_data = {}
+ self.layers = []
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = ConvertProjectReader()
+ reader.from_etree(etree, configuration.get_storage().get_path())
+
+ impl = ConvertProjectImpl(resource_ref, configuration)
+ impl.project_data = reader.project_data
+ impl.layers = reader.layers
+ return impl
+
+ def from_etree(self, etree, old_structure_root = ""):
+ self.project_data = self.parse_attributes(etree, "targetProject")
+ self.layers = self.parse_layers(etree)
+ for fe in self.parse_foreach(etree, old_structure_root):
+ self.layers.append(fe)
+
+ #for l in self.layers:
+ #print l
+ return
+
+ def parse_foreach(self, etree, old_structure_root):
+ layersTmp = []
+ for fe in etree.findall("{%s}foreach" % self.namespaces[0]):
+ variable = fe.get("variable")
+ data = fe.get("data")
+ folders = []
+ for item in os.listdir(os.path.join(old_structure_root, data)):
+ if os.path.isdir(os.path.join(old_structure_root, data, item)) and item != '.svn':
+ folders.append(item)
+
+ for folder in folders:
+ mapping_data = {variable: folder}
+ for layer in fe.findall("{%s}layer" % self.namespaces[0]):
+ layersTmp.append(self.parse_layer(layer, mapping_data))
+
+ return layersTmp
+
+ def parse_layers(self,etree):
+ layersTmp = []
+ for layer in etree.findall("{%s}layer" % self.namespaces[0]):
+ layersTmp.append(self.parse_layer(layer))
+
+ return layersTmp
+
+ def parse_layer(self, etree, mapping_data=None):
+ path = self.handleMapping(etree.get("path"), mapping_data)
+
+ layerObject = ConvertProjectLayer(path)
+ for folder in etree.findall("{%s}folder" % self.namespaces[0]):
+ layerObject.addFolder(self.parse_folder(folder, layerObject, mapping_data))
+
+ for f in etree.findall("{%s}file" % self.namespaces[0]):
+ layerObject.addFile(self.parse_file(f, layerObject, mapping_data))
+
+ return layerObject
+
+ def parse_folder(self, etree, parent, mapping_data=None):
+ path = self.handleMapping(etree.get("path"), mapping_data)
+
+ folderObject = ConvertProjectFolder(path, parent)
+ for filter in etree.findall("{%s}filter" % self.namespaces[0]):
+ #Remove includes supported only for files.
+ folderObject.addFilter(self.parse_filter(filter, folderObject, mapping_data))
+ return folderObject
+
+ def parse_file(self, etree, parent, mapping_data=None):
+ path = self.handleMapping(etree.get("path"), mapping_data)
+ type = self.handleMapping(etree.get("type"), mapping_data)
+
+ fileObject = ConvertProjectFile(path, type, parent)
+ for filter in etree.findall("{%s}filter" % self.namespaces[0]):
+ fileObject.addFilter(self.parse_filter(filter, fileObject, mapping_data))
+
+ metaElement = etree.find("{%s}meta" % self.namespaces[0])
+ namespacePattern = re.compile("\{(.*)\}(.*)")
+ metaArray = [] #tag, value, ns, attrs
+ if metaElement:
+ for item in metaElement.getiterator():
+ mo = namespacePattern.search(item.tag)
+ if mo:
+ if mo.group(2) != "meta":
+ tmpArray = []
+ tmpArray.append(mo.group(2)) #Tag name
+ tmpArray.append(item.text) #value
+ tmpArray.append(mo.group(1)) #Namespace
+ tmpDict = {}
+ for attribute in item.keys():
+ tmpDict[attribute] = item.get(attribute)
+ tmpArray.append(tmpDict)
+ metaArray.append(tmpArray)
+
+ descElement = etree.find("{%s}desc" % self.namespaces[0])
+ description = ""
+ if descElement != None:
+ description = descElement.text
+
+ fileObject.addMeta(metaArray)
+ fileObject.addDescription(description)
+ return fileObject
+
+ def parse_filter(self, etree, parent, mapping_data=None):
+ """
+ """
+ data = self.handleMapping(etree.get("data"), mapping_data)
+ action = self.handleMapping(etree.get("action"), mapping_data)
+ remove_includes = self.handleMapping(etree.get("remove_includes"), mapping_data)
+ recursive = self.handleMapping(etree.get("recursive"), mapping_data)
+
+ return ConvertProjectFilter(action, data, parent, remove_includes, recursive)
+
+
+ def parse_rule(self, etree, parent):
+ return {"name": etree.get("name"), "type": etree.get("type"), "data": etree.get("data")}
+
+ def parse_attributes(self, etree, tagName):
+ tmpDict = {}
+ tmpElement = etree.find("{%s}%s" % (self.namespaces[0], tagName))
+ for attribute in tmpElement.keys():
+ tmpDict[attribute] = tmpElement.get(attribute)
+ return tmpDict
+
+ def handleMapping(self, data, mapping):
+ """
+ """
+
+ retStr = data
+
+ if mapping != None and data != None:
+ for key in mapping.keys():
+ retStr = retStr.replace(key, mapping[key])
+ return retStr
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/create_project.convertprojectml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/create_project.convertprojectml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/confml/family_x.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/confml/family_x.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+
+
+
+ 300
+ false
+ 3.1456
+ 3
+ Family X
+
+ 50.1
+ 1
+ Test 1
+ false
+ 0
+
+
+ 50.2
+ 2
+ Test 2
+ true
+ 1
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/confml/product_x.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/confml/product_x.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+ 500
+ true
+ Product X
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Euro/confml/VariantData_product_x_Euro.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Euro/confml/VariantData_product_x_Euro.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+ testing
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Euro/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Euro/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/French/confml/VariantData_product_x_French.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/French/confml/VariantData_product_x_French.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+ français
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/French/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/French/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/German/confml/VariantData_product_x_German.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/German/confml/VariantData_product_x_German.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+ deutsch
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/German/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/German/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Greek/confml/VariantData_product_x_Greek.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Greek/confml/VariantData_product_x_Greek.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+ ελληνική γλώσσα
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Greek/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Greek/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test/implml/create_project.convertprojectml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test/implml/create_project.convertprojectml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Version1
+ Platform1
+ Date1
+ Release1
+ Editor1
+
+ Description1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test2/dummy.iby
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test2/dummy.iby Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test3/implml/create_project.convertprojectml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test3/implml/create_project.convertprojectml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Version1
+ Platform1
+ Date1
+ Release1
+ Editor1
+
+ Description1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test3/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test3/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform1_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform1_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+ Version1
+ Platform1
+ Date1
+ Release1
+ Editor1
+
+Description1
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform2_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform2_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/confml/bitmask_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/confml/bitmask_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+
+
+
+ Feature with bitmask flags
+
+ A boolean setting for bit 0
+
+
+ A boolean setting for bit 1
+
+
+ A boolean setting for bit 2
+
+
+ A boolean setting for bit 3
+
+
+ A boolean setting for bit 4
+
+
+ A boolean setting for bit 5
+
+
+
+
+ true
+ false
+ true
+ false
+ true
+ false
+
+
+
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/bitmask_test_12341002.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/bitmask_test_12341002.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/feature1_12341000.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/feature1_12341000.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/feature1_12341001.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/feature1_12341001.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/feature1_sequence.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/implml/feature1_sequence.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ , , , , , ,
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform2/confml/feature2.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform2/confml/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform2/implml/feature2_ABCD0000.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform2/implml/feature2_ABCD0000.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform2/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform2/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Euro_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Euro_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_French_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_French_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_German_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_German_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Greek_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Greek_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/bitmask_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/bitmask_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+
+
+
+ Feature with bitmask flags
+
+ A boolean setting for bit 0
+
+
+ A boolean setting for bit 1
+
+
+ A boolean setting for bit 2
+
+
+ A boolean setting for bit 3
+
+
+ A boolean setting for bit 4
+
+
+ A boolean setting for bit 5
+
+
+
+
+ true
+ false
+ true
+ false
+ true
+ false
+
+
+
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/bitmask_test_12341002.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/bitmask_test_12341002.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1_12341000.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1_12341000.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1_12341001.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1_12341001.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1_sequence.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/feature1_sequence.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ , , , , , ,
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/platform1.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform1/platform1.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform2/feature2.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform2/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform2/feature2_ABCD0000.crml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform2/feature2_ABCD0000.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform2/platform2.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/platform2/platform2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convert.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convert.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convertpluginlayer/implml/create_project.convertprojectml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convertpluginlayer/implml/create_project.convertprojectml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Version1
+ Platform1
+ Date1
+ Release1
+ Editor1
+
+ Description1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convertpluginlayer/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convertpluginlayer/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/dummy.bin
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/dummy.hrh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/dummy.hrh Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/dummy.iby
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/dummy.iby Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/dummy.ini
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/family_x.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/family_x.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/image_conf_family_x.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/image_conf_family_x.mk Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/product_x/product_x.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/product_x/product_x.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/some_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/Euro/VariantData_product_x_Euro.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/Euro/VariantData_product_x_Euro.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/French/VariantData_product_x_French.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/French/VariantData_product_x_French.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/German/VariantData_product_x_German.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/German/VariantData_product_x_German.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/Greek/VariantData_product_x_Greek.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/variants/language/product_x/Greek/VariantData_product_x_Greek.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/assets/s60/implml/file1.convertprojectml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/assets/s60/implml/file1.convertprojectml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/assets/s60/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/assets/s60/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/family/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/family/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/family/product/root.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/family/product/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/family/root.confml
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/family/root.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/product.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/product.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/unittest_convertprojectml_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/unittest_convertprojectml_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+
+import __init__
+from projectconvertplugin import convertproject
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+from testautomation.base_testcase import BaseTestCase
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+temp_dir = os.path.join(ROOT_PATH, "temp")
+testdata = os.path.join(ROOT_PATH,'project')
+
+class TestConvertProjectPlugin(BaseTestCase):
+
+ def test_example_parse_prj(self):
+ output_dir = os.path.join(temp_dir, "new_project2")
+ if os.path.exists(output_dir):
+ shutil.rmtree(output_dir)
+
+ fs = filestorage.FileStorage(testdata)
+ p = api.Project(fs)
+ config = p.get_configuration('product.confml')
+ impls = plugin.get_impl_set(config, r'file1\.convertprojectml$')
+ self.assertEquals(1, len(impls))
+ impl = iter(impls).next()
+ self.assertTrue(isinstance(impl, convertproject.ConvertProjectImpl))
+
+ def test_generate(self):
+ output_dir = os.path.join(temp_dir, "new_project")
+ if os.path.exists(output_dir):
+ shutil.rmtree(output_dir)
+ expected_dir = os.path.join(ROOT_PATH, "expected/new_project")
+ oldPath = os.path.join(ROOT_PATH,'old_structure/epoc32/rom/config')
+
+ fs = filestorage.FileStorage(oldPath)
+ p = api.Project(fs)
+ config = p.get_configuration('convert.confml')
+ impls = plugin.get_impl_set(config,'\.convertprojectml$')
+ impls.output = output_dir
+ impls.generate()
+
+ self.assert_dir_contents_equal(expected_dir, output_dir, ['.svn'])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from projectconvertplugin import __version__
+
+setup(
+ name = "projectconvertplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+ test_suite = "projectconvertplugin.tests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine Project converter plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['convertprojectml = projectconvertplugin.convertproject:ConvertProjectReader']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from themeplugin import __version__
+
+setup(
+ name = "conethemeplugin",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests"]),
+
+ # metadata for upload to PyPI
+ author = "",
+ author_email = "",
+ description = "Configuration Engine makefile generation plugin",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True,
+
+ # entrypoint info
+ entry_points={'cone.plugins.implmlreaders': ['thememl = themeplugin.maketheme:ThemeImplReader']}
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+__version__ = 0.1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/maketheme.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/maketheme.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,298 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import re
+import os
+import sys
+import logging
+import xml.parsers.expat
+import unzip
+import shutil
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+
+from cone.public import exceptions,plugin,utils,api
+from themeplugin import theme_function
+from theme_resource import ThemeResource
+from theme_container import ThemeContainer, ActiveTheme
+
+class ThemeImpl(plugin.ImplBase):
+ """
+ This class provides converting *.tpf files to target device
+
+
+ Building process:
+ 1. All tpf files are founded in the cpf file according to "preinstalled directories"
+ and "CVC settings" which are defined in the thememl file.
+
+ 2. The tpf files are extracted to temporary directories. Every tpf file has self temporary directory
+
+ 3. *.tdf, *.svg files are builded to *.mbm, *.skn,... by using Carbide.UI command-line.
+ The path of Carbide.UI is defined in the thememl file.
+
+ Here is two possible cases:
+ 3a) The theme has defined UID number in thememl file.
+ The Carbide.UI is run with parameter -uid %number%.
+ Then this UID number (after converting to decimal format) is saved to
+ platform setting in the step 5
+
+ 3b) The theme has not defined UID number
+ The Carbide.UI is run without parameter -uid %number% and then
+ the PID number is getted from *.pkg file and setted to platform setting in the decimal format
+ in the step 5
+
+ 4. *.mbm, *.skn,... are copied to output directory according to content of the pkg file.
+ The *.pkg file contains the record where the *.mbm, *.skn,... are be copied.
+ Sample: "themepackage.mbm" - "private\10207114\import\99d49b086e6097b8\themepackage.mbm"
+
+ 5. UID or PID number are saved to platform setting which is defined in the thememl file
+ 6. Temporary directories are removed
+ """
+
+
+ IMPL_TYPE_ID = "thememl"
+ DEFAULT_INVOCATION_PHASE = 'pre'
+
+
+ def __init__(self,ref,configuration):
+ """
+ Overloading the default constructor
+ """
+ plugin.ImplBase.__init__(self,ref,configuration)
+ self.logger = logging.getLogger('cone.thememl')
+
+ def build(self):
+ """
+ Building process of themes
+ """
+ # Get absolute path so that copying works correctly
+ # despite working directory changing
+ abs_output = os.path.abspath(os.path.join(self.output, "content"))
+
+ # get *.tpf files from the configuration
+ list_tpf = self.list_tpf_files(self.list_active_theme, self.list_theme_dir)
+
+ theme_container = ThemeContainer(list_tpf,self.configuration)
+ theme_container.carbide = self.carbide
+ theme_container.create_themes()
+ theme_container.prepare_active_themes(self.list_active_theme)
+ theme_container.build_theme(self.theme_version)
+ theme_container.copy_resources_to_output(abs_output)
+ theme_container.set_active_PID_to_model()
+ theme_container.removeTempDirs()
+
+
+
+ def list_tpf_files(self,list_active_theme, list_theme_dir):
+ """
+ returns the list of tpf files which are in the configuration
+ """
+ list_tpf=[]
+ default_view = self.configuration.get_default_view()
+
+ for active_theme in list_active_theme:
+ path=active_theme.get_setting_ref().replace("/",".")
+ feature = default_view.get_feature(path+".localPath")
+ setting = feature.get_data()
+ if setting != None:
+ list_tpf.append(setting.get_value())
+
+ for theme_dir in list_theme_dir:
+ theme_dir=theme_dir.replace("/",".")
+ feature = default_view.get_feature(theme_dir+".localPath")
+ setting = feature.get_data()
+ if setting != None:
+ list_tpf.append(setting.get_value())
+
+
+ return self.find_tpf_files(list_tpf)
+
+
+ def find_tpf_files(self, list_tpf_path):
+ """
+ finds *.tpf files in the data container
+ """
+ list_tpf={}
+
+ datacontainer = self.configuration.layered_content()
+ contentfiles = datacontainer.flatten()
+ for reskey in contentfiles.keys():
+ respath = contentfiles[reskey]
+
+ if respath.endswith(".tpf"):
+ # Strip file name from the resource path
+ respath_basename = os.path.split(respath)[0]
+
+ for tpf_path in list_tpf_path:
+ # os.path.split() strips trailing slash, so do that here too
+
+ tpf_path = "/content/" + tpf_path
+ if tpf_path.endswith(".tpf"):
+ if respath.endswith(tpf_path):
+ list_tpf[respath]=0
+ break
+
+ if tpf_path.endswith('/'):
+ tpf_path = tpf_path.rstrip('/')
+ if respath_basename.endswith(tpf_path):
+ list_tpf[respath]=0
+ break
+
+
+
+
+
+ return list_tpf.keys()
+
+
+ def generate(self, context=None):
+ """
+ Generate the given implementation.
+ """
+ self.parse_impl()
+ self.build()
+
+ return
+
+ def generate_layers(self,layers):
+ """
+ Generate the given Configuration layers.
+ """
+ self.logger.info('Generating layers %s' % layers)
+ self.create_output(layers)
+ return
+
+ def has_ref(self,ref):
+ """
+ @returns True if the implementation uses the given ref as input value.
+ Otherwise return False.
+ """
+ return None
+
+ def parse_impl(self):
+ if self.configuration:
+ resource =self.configuration.get_resource(self.ref)
+ reader = ThemeImplReader()
+ try:
+ self.logger.info('Parses %s' % self.ref)
+ reader.fromstring(resource.read())
+ self.carbide = reader.carbide
+ except (SyntaxError),e:
+ logging.getLogger('cone.thememl(%s)' % resource.get_path()).error('Invalid xml in layer root file. Exception: %s' % (e))
+ raise exceptions.ParseError('Invalid xml in layer root file (%s). Exception: %s' % (resource.get_path(),e))
+ self.list_theme_dir=reader.list_theme_dir
+ self.list_active_theme=reader.list_active_theme
+ self.theme_version = reader.theme_version
+ resource.close()
+
+ return
+
+ def list_output_files(self):
+ """
+ Return a list of output files as an array.
+ """
+ # What to return if the output files cannot be known in advance?
+ return []
+
+
+class ThemeImplReader(plugin.ReaderBase):
+ """
+ Parses a single thememl file
+ """
+ NAMESPACE = 'http://www.s60.com/xml/thememl/1'
+ FILE_EXTENSIONS = ['thememl']
+
+ def __init__(self):
+ self.namespaces = [self.NAMESPACE]
+ self.list_theme_dir = []
+ self.list_active_theme = []
+ self.theme_version = ""
+ self.logger = logging.getLogger('cone.thememl')
+ self.carbide = r"C:\Program Files\Nokia\Carbide.ui Theme Edition 3.4"
+
+ @classmethod
+ def read_impl(cls, resource_ref, configuration, etree):
+ reader = ThemeImplReader()
+ reader.parse_thememl(etree)
+
+ impl = ThemeImpl(resource_ref, configuration)
+ impl.list_theme_dir = reader.list_theme_dir
+ impl.list_active_theme = reader.list_active_theme
+ impl.theme_version = reader.theme_version
+ return impl
+
+ def fromstring(self, xml_as_string):
+ etree = ElementTree.fromstring(xml_as_string)
+ self.parse_thememl(etree)
+
+ def parse_thememl(self,etree):
+
+ list_setting_uid={}
+
+ #parses the version of the theme
+ el_theme_version= etree.find("{%s}themeVersion" % self.namespaces[0])
+ if el_theme_version != None:
+ self.theme_version = el_theme_version.text
+
+ car= etree.find("{%s}carbideuiPath" % self.namespaces[0])
+ envpattern = ".*(%(.*)%).*"
+ if car != None:
+ mo = re.match(envpattern, car.text)
+ if mo:
+ if os.environ.has_key(mo.group(2)):
+ self.carbide = car.text.replace(mo.group(1), os.environ[mo.group(2)])
+ else:
+ self.carbide = car.text
+ else:
+ self.carbide = car.text
+
+
+ #parses the path of directories where are tpf files
+ el_list_theme_dir = etree.findall("{%s}themeDir" % self.namespaces[0])
+ for el_theme_dir in el_list_theme_dir:
+ if el_theme_dir != None:
+ self.list_theme_dir.append(el_theme_dir.text)
+
+ #parses the active themes and theirs ref setting and platform settings
+ el_list_active_theme = etree.findall("{%s}activeTheme" % self.namespaces[0])
+ for el_active_theme in el_list_active_theme:
+ uid = el_active_theme.get("uid")
+ active_theme = ActiveTheme()
+
+ active_theme.set_uid(uid)
+ for el_ref_setting in el_active_theme.getiterator("{%s}refSetting" % self.namespaces[0]):
+ active_theme.set_setting_ref(el_ref_setting.text)
+
+
+ for el_setting_uid in el_active_theme.getiterator("{%s}platformUID" % self.namespaces[0]):
+ setting_uid = el_setting_uid.text
+ if list_setting_uid.has_key(setting_uid):
+ raise exceptions.ParseError('The file contains duplicate setting uid: %s' % setting_uid)
+ else:
+ list_setting_uid[setting_uid]=0
+ active_theme.set_setting_uids(setting_uid)
+
+ self.list_active_theme.append(active_theme)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# Import common plug-in initialization
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+plugin_utils.plugin_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/.metadata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/.metadata Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/.project
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/.project Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+
+
+ E75_v053
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerBuilder
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerNature
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_2DigitDialing.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_2DigitDialing.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ 2 Digit Dialing.
+
+ 2 Dialing. Default is disabled
+
+
+
+
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ActiveIdleNotifiers.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ActiveIdleNotifiers.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+
+
+ Notification components: missed calls, new messages (device inbox), and new voice messages are located on one row of the device. It is possible to configure the notifiers on/off separately. If a notification component is turned off, the notifications are shown as traditional pop-up notifications.
+
+ Up to two different e-mail accounts for each mode can be configured to be visible on the Home screen. It is not possible to customize e-mail notifiers as they are only available when the e-mail account is first activated.
+
+
+ Calendar and To-do components provide dynamically updated information from Calendar entries and ToDo notes. If there is no data to show, "No calendar events for today" note is visible on the Home screen view.
+
+
+ The Music Player component shows the music tracks that are being played by the Music Player. If there is no data to show, this UI area is empty.
+
+
+ The Visual radio plug-in shows the name or frequency of the radio channel that is being played by Visual radio in the background. The icon also shows whether Visual radio service is available for the current channel.
+
+
+ This component shows dynamically updated information about available WLAN networks and shortcut to WLAN wizard that enables selecting WLAN network and defining access point for it. If scanning is set to off, there is 'WLAN scanning off' in Home screen view.
+
+
+ This component shows dynamically updated information about available WLAN networks and shortcut to WLAN wizard that enables selecting WLAN network and defining access point for it. If scanning is set to off, there is 'WLAN scanning off' in Home screen view.
+
+
+ This plug-in provides easy access to Voice over IP settings wizard, providing options to launch Voice over IP setup wizard or hide the plug-in from the Home screen.
+
+
+ The Mobile search plug-in allows the user to initiate a search for content in the device or in the Internet directly from Home screen. User can click on the plug-in and write the search term.
+
+
+ The SIM Application Toolkit shows messages from an application residing on the SIM card.
+
+
+
+
+true
+true
+true
+true
+true
+true
+true
+true
+true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ActiveIdleOther.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ActiveIdleOther.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+ Easy Dialing allows user to start dialling from Home Screen to a contact without first starting Phonebook application. The name input is predictive (subject to restrictions by input language), and the contacts are matched so that each character only requires one key press. Typing more narrows down the options. User is able to use the number that was just typed, or select one of the name matches.
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_AppShell323.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_AppShell323.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+ Application Shell customization.
+
+ Folder containing Application Shell configuration files: appshelldata.xml, appshelldata.dtd, appshellapplications.properties
+
+
+
+
+
+
+UI/Application Menu
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_BluetoothDiscoverability.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_BluetoothDiscoverability.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+ Default state of Bluetooth in the terminal: discoverable ("Shown To All") or hidden.
+
+ Default state of Bluetooth in the terminal: discoverable ("Shown To All") or hidden.
+
+
+
+false
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_CPHSALS.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_CPHSALS.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ CPHS is an extension to the GSM specification that adds several convenience and usability enhancements to the way GSM phones and SIM cards operate. Examples of CPHS enhancements include single-key access to a standard voicemail number stored on the SIM, and a message-waiting indicator to alert users to new voicemail messages. CPHS also provides carriers with greater control and flexibility over the carrier name that is displayed on the phone. CPHS also includes the ability to control certain network-based features from the phone interface, including call forwarding, call waiting, and caller-ID. CPHS is not an official part of the GSM specification. It was developed by the PCN Association rather than the GSM Association. Nonetheless, CPHS has been popular among carriers. Many European and American GSM carriers require it, and so newer GSM phones from most major manufacturers include CPHS functionality.
+
+ If ALS is set as ON, the functionality of toggling from General to Silent profile by long press # key will be disabled. CPHS and ALS can be set ON and OFF in the customer variants of the standard transceiver. CPHS and ALS can never be both set ON at the same time.
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_CellInfoDisplay.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_CellInfoDisplay.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ Cell Info Display Setting (Cell Broadcast Reception)
+
+ Cell Info Display Setting (Cell Broadcast Reception). "On" when checked. Cell info display is "Off" by default in the standard transceiver. This setting is set "On" by default for countries in which the GSM regulatory authority requires it.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_CustomerMenu.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_CustomerMenu.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,36 @@
+
+
+ Often referred to as the Operator Menu, the Customer Menu is an application that launches the browser as an embedded application with a predefined URL as parameter. The URL defines the xHTML Startup page that is shown when the Customer Menu application is launched, for example www.customername.com/index.html. The URL also defines the customer domain URL path, for example www.customername.com/. All user-browsed xHTML pages belonging to that path are automatically stored in the Customer Menu cache.The Customer Menu application can be configured as a shortcut just like any other application. In Main menu, the Customer Menu is placed by default to 11th position. When the Customer Menu is enabled, Help moves from position 11 to 12 and Apps moves from 12 to 13, which is not visible until the user scrolls the menu cursor.
+
+ Customer menu icon that will be present in Application Grid. Size: 65 x 65 pixels. Format: SVGT (preferred) or BMP. Color depth: 24 bit
+
+
+
+
+ Customer menu bitmask when using BMP menu icon. Size: 65 x 65 pixels. Format: BMP. Color depth: 8 bit
+
+
+
+
+ The text caption for Customer Menu icon
+
+
+ Target URL for Operator Menu. The URL defines the xHTML Start-up page that will be shown when the Customer Menu application is launched (e.g. “www.customername.com/index.htmâ€). The URL also defines the customer domain URL path (e.g. “www.customername.comâ€).
+
+
+ Data stored in the Customer Menu cache is preserved in the device memory and can be accessed even after the Browser session is ended and through power cycles of the device. File format: xHTML files. Customers provide the xHTML pages to be pre-installed in the Customer Menu Cache.The max. amount of data that can be stored in the Customer Menu cache is 300 KB
+
+
+
+
+ In “mm/yyyy†format. Customers define the expiration date of the xHTML page(s). After that date, the cache content will no longer be used and Operator icon will launch URL instead.
+
+
+
+
+
+UI/Customer Menu/Cache
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_InstantMessaging.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_InstantMessaging.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,74 @@
+
+
+
+ IM (Instant Messaging) settings
+
+ Server name. Max 30 chars.
+
+
+ Max 100 chars.
+
+
+ Max 50 chars.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Alert tone for Instant Messaging.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_MMS.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_MMS.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+
+ Additional mappings for MMS image and size settings
+
+ Image size in pixels to which the picture is coverted when is transferred as part of and MMS message.
+
+
+
+
+ Defines the maximum possible size for an MMS to be sent in bytes. It is the application's responsibility to assert this. For UI use only.
+
+
+
+
+
+
+
+ Defines the maximum possible size for a received MMS in bytes. This value should be at least 4 kilobytes larger than KMmsEngineMaximumSendSize in order to reserve space for MMS headers and attachment MIME headers.
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_NokiaPCInternetAccess.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_NokiaPCInternetAccess.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+
+
+Customizations of PC application "Nokia PC Internet Access"
+
+ Customer logo file. Format: Portable Network Graphics with transparent background. Size 280x40.
+
+
+
+
+ NPCIA autolaunches the default web browser of the PC. Default starting page of the browser can be set through NPCIA (when browser is launched by NPCIA)
+
+
+ Located in in NPCIAs’ ‘Settings’ view. Can be phone number and/or link to operator webpage.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_OperatorLogo.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_OperatorLogo.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+
+
+The Nokia E75 supports color logos in addition to the traditional black and white customer logos. Customer logos may be predefined in the default settings for the device or downloaded by the user. The customer logo is stored together with the MNC and MCC info of the home network in the device and will be displayed when the user is in the home network. The customer logo replaces the standard customer name.
+
+ Operator-specific Mobile Country Codes (MCCs) defined in ITU E.212 ("Land Mobile Numbering Plan") for use in identifying mobile stations in wireless telephone networks, particularly GSM and UMTS networks.
+
+
+ Operator-specific Mobile Network Code(MNC) is used in combination with a Mobile Country Code (MCC) (also known as a "MCC / MNC tuple") to uniquely identify a mobile phone operator/carrier using the GSM, CDMA, iDEN, TETRA and UMTS public land mobile networks and some satellite mobile networks
+
+
+ Operator logo file. Format: BMP or SVG. Maximum size 134x33 pixels. Name must be Logo_MCC_MNC_PROG.svg or Logo_MCC_MNC_PROG.bmp, where MCC and MNC are mobile country code and mobile network code.
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_Preinstalled.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_Preinstalled.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,186 @@
+
+
+ Customer-defined pre-installed content. Please note that the total size of the User Data Area content size must not exceed 5 Mbytes.
+
+
+ Max 6 mms, max size 35K. Binary format (encoding according to MMS encapsulation specification)
+
+ Pre-Installed MMS
+
+
+
+
+
+
+
+ Pre-Installed Images. Size up to 5MP (2560x1920 pixels), format JPEG. No EXIF data allowed
+
+
+
+
+
+
+ Pre-Installed Streaming links. Format is .ram file.
+
+
+
+
+
+ Pre-Installed Music Clips.
+
+
+
+
+
+ Pre-Installed Video Clips.
+
+
+
+
+
+ Default Ringtone in General Profile. Any supported media file.
+
+
+
+
+
+
+
+ Default ringtone for incoming message event in General Profile. Any supported media file.
+
+
+
+
+
+ Default ringtone for video call event in General Profile. Any supported media file.
+
+
+
+
+
+ Default tone for incoming E-Mail in General profile. Any supported media file.
+
+
+
+
+
+
+ Default tone for Calendar alarm. Any supported media file.
+
+
+
+
+
+ Default tone for Clock alarm. Any supported media file.
+
+
+
+ Pre-Installed Themes. Format is Theme project archive zip file with extesion .tpf, containing the theme project and main .tdf file.
+
+
+
+
+
+ Complementary applications pre-Installed to device ROM. Will NOT be uninstallable by end-users. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+
+
+
+ Complementary applications pre-Installed to device ROM. Will NOT be uninstallable by end-users. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+
+
+
+ Complementary applications pre-loaded to device. Offerecd for installation to the end-user. Format is Symbian sisgned .sis file or Java MIDP .jar + .jad. Ensure that application did pass Simbian Signed or Java Verified acceptance.
+
+
+
+
+
+ Symbian certificates for trusted software installations.
+
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+
+ Allows installation of native Symbian OS applications (on/off)
+
+
+ Allows to validate OCSP revocation responses (on/off)
+
+
+
+
+
+ Java MIDP certificates for trusted software installations.
+
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+
+ Trusted application domain: Customer or Third-party.
+
+
+
+
+
+
+ Certificates for Internet services: SSL/TLS (HTTPS,SecureIMAP, etc.) connections.
+
+ Certificate file. Must be in X.509 CA format.
+
+
+
+ Allows to validate OCSP revocation responses (on/off)
+
+
+
+
+
+
+
+
+
+
+
+ Media/Images
+
+
+
+ Streaming Links
+
+
+
+ Media/Music
+
+
+
+ Media/Videos
+
+
+
+ UI/Themes
+
+
+
+ Applications/Pre-installed to UDA
+
+
+
+ Applications/Pre-installed to MMC
+
+
+
+ Applications/Bundled
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_RightSoftkey.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_RightSoftkey.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+
+
+ The right soft key (RSK) in idle mode can be configured to launch a customer defined application or URL. The RSK label can be branded with a graphic only if it is a URL. The left soft key (LSK) is always a text string and is not customizable. The end user is able to personalize both the left and right soft keys.
+
+ Right Softkey Customization
+
+
+ Right Softkey caption text (if RSK is not customized as image). 12 characters max (5 for Chinese variants).
+
+
+ Size: 115 x 22 pixels Format: SVGT (preferred) or BMP
+
+
+
+
+ Right softkey BMP mask. Applicable only if BMP format is used.
+
+
+
+
+ Right Softkey target URL (if target is defined as a web site).
+
+
+ Right Softkey target Application UID (if target is an application). Format is a hexadecimal number (0x00000000).
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_StartupShutdownAnimations.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_StartupShutdownAnimations.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,52 @@
+
+
+ Startup animation. The customer specific startup element can contain either a still image or an animation with or without a customer specified tone.
+
+ Time in milliseconds. Display time for still image is max 3 seconds (3000 msec), for animation 2.5 max seconds.
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+
+
+ Shutdown animation. The customer specific shutdown element can contain either a still image or an animation with or without a customer specified tone.
+
+ Time in milliseconds. Display time for still image is max 3 seconds (3000 msec), for animation 2.5 max seconds.
+
+
+
+
+ Sound tone played during animation. Animation is displayed at speed of 10 fps. If the optional tone is longer than 2.5 seconds, the last image will be displayed until the tone has finished.
+
+
+
+
+
+ Folder with animation frames. Filenames must be ordered by numbering frames in the correct sequence. Frame delay is fixed at 100ms to 250ms depending on phone model. Last frame will be displayed for duration remaining to defined Animation Duration setting.
+
+
+
+
+ 3000
+
+ UI/Start-up Animation
+
+
+
+
+ 3000
+
+ UI/Shutdown Animation
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_Streaming.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_Streaming.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,123 @@
+
+
+ Streaming Settings
+
+ Use proxy for streaming
+
+
+
+
+ Programmed (max.length 1000 characters)
+
+
+ Programmed (1-9999)
+
+
+ Programmed (max.length 100 characters)
+
+
+ Limit for online time spent in streaming
+
+
+
+
+ User-selectable value for online streaming time (if limiting is enabled)
+ (1 – 30 minutes)
+
+
+ 1024 (equal or smaller than Highest UDP port) (default 6970)
+
+
+ 65535 (equal or bigger than Lowest UDP port)(default 32000)
+
+
+ GPRS bandwidth limit for streaming
+
+
+
+
+
+
+
+
+ User defined (5 – 99.99 kbps)
+
+
+ EGPRS bandwidth limit for streaming
+
+
+
+
+
+
+
+ User defined (5 – 199.99 kbps)
+
+
+ UMTS bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+ User defined (5 – 999.99 kbps)
+
+
+ WLAN bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User defined (kbps)
+
+
+ HSDPA bandwidth limit for streaming
+
+
+
+
+
+
+
+
+
+ User defined (5 – 3999.99 kbps)
+
+
+
+
+ No
+
+ 554
+
+ Unlimited
+ 1
+ 6970
+ 32000
+ 40
+ 5
+ 89
+ 5
+ 384
+ 5
+ 1430
+ 5
+ user
+ 5
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_SyncML.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_SyncML.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,161 @@
+
+
+ SyncML Settings.
+
+ Maximum length 50 characters.
+
+
+ 1.1, 1.2 (default)
+
+
+
+
+ Server ID
+
+
+ Data bearer for server connection
+
+
+
+
+
+ Access point to use for server connetion
+
+
+
+
+ Maximum length 150 characters.
+
+
+ 80 (default), 1-65535
+
+
+ Server account: username
+
+
+ Server account: password
+
+
+ Policy for sync requests
+
+
+
+
+
+ Username for Access Point connection
+
+
+ Password for Access Point connection
+
+
+ Type of syncronization
+
+
+
+
+
+
+
+
+
+ Include Contacts in Sync ON/OFF
+
+
+
+ Include Calendar in Sync ON/OFF
+
+
+
+ Include Notes in Sync ON/OFF
+
+
+
+ Include E-mail in Sync ON/OFF
+
+
+
+ Include Music in Sync ON/OFF
+
+
+
+ Include MSyncService in Sync ON/OFF
+
+
+
+ Include Images in Sync ON/OFF
+
+
+
+ Include MMS in Sync ON/OFF
+
+
+
+ Include Video in Sync ON/OFF
+
+
+
+ Include SMS in Sync ON/OFF
+
+
+
+ Include Bookmarks in Sync ON/OFF
+
+
+
+
+
+
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+ Maximum length 50 characters.
+
+
+
+
+
+
+80
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ThemeWallpaperScreensaver.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ThemeWallpaperScreensaver.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,49 @@
+
+
+
+ Default Theme to be set on device. Select from the set of pre-installed themes.
+
+ Default Theme to be set on device. Select from the set of pre-installed themes.
+
+
+
+
+
+
+ Default wallpaper
+
+ Size: 240X234 pixels Format: SVGT (preferred) or BMP. 24 bit. The end user can select to change this to either a different single image or select multiple images to run in a wallpaper slide show.
+
+
+
+
+
+
+ Screensaver
+
+ Screensaver file. Format is animated GIF.
+
+
+
+
+ Duration the animation will run before reverting to default screensaver in minutes. Min 1 minute, max 30 minutes.
+
+
+ Duration of display lights being turned on while the animation runs in seconds. 0 = no lights, max 30 seconds.
+
+
+
+
+
+
+ UI/Armi2.tpf
+
+
+
+
+
+3
+15
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_VoiceMailbox.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_VoiceMailbox.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+ The device number of the customer’s voice mailbox may be programmed into the device during production or in service. Voice mailbox feature may be activated in two different ways: CSP (Customer Service Profile) support is enabled in product profile AND voice mailbox numbers can be found from customer’s SIM card
+
+ Maximum allowed length is 50 characters.
+
+
+ Maximum allowed length is 50 characters.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ZeroPlusSend.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/CVC_ZeroPlusSend.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+ 0 + SEND is used in the US as access number to national operator assistance both in landline and wireless networks.
+
+ 0 + SEND is used in the US as access number to national operator assistance both in landline and wireless networks. Default is off.
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/confml/test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+
+
+ Testing for deference
+
+
+
+
+ Hello world
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/cvc_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/cvc_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/cvc_view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/cvc/cvc_view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,219 @@
+
+
+
+ Custom modeled ConfMLs for E75 customization according to E75 Customization Guidelines
+
+ Settings for standard S60 Platform applications
+
+
+ Browser (xHTML) settings
+
+
+ Calendar
+
+
+ Settings for Device Manager application.
+
+
+ Media Player
+
+
+ Voice Recorder
+
+
+ Phonebook
+
+
+ Logs
+
+
+ Camcorder
+
+
+ Clock
+
+
+ Profiles
+
+
+ Positioning
+
+
+ Instant Messaging
+
+
+
+
+ Settings for personal communication and connection methods
+
+
+ Nokia NXX has StartUp Settings application. It configures access point settings based on a SIM card�s MCC and MNC and the access point information supplied to Nokia by the network operators.
+
+
+ If the Customer specifies MMS settings (including Access points) in their variant then the transceiver will be able to receive MMS messages straight away after having been powered-up.
+
+
+ SMS Settings
+
+
+ Postcard settings
+
+
+ Customers may choose to define one set of common settings for the e-mail client in the Messaging application of the device.
+
+
+ Messaging
+
+
+ Bluetooth
+
+
+ Streaming
+
+
+
+ Mobile TV
+
+
+ Settings for voice and video mailboxes
+
+
+
+
+ System settings of S60 platform
+
+
+ Accessory Profiles
+
+
+ SyncML
+
+
+
+
+
+ Light Senso
+
+
+ Java Application Settings
+
+
+ Other
+
+
+
+
+
+
+ Telephony
+
+
+ Firmware update Over The Air
+
+
+ Keypad lock settings
+
+
+ Service Messages
+
+
+ Vibra
+
+
+ TV-out
+
+
+ Software Install
+
+
+
+ Settings for branding, user interface and look & feel
+
+
+ Often referred to as the Operator Menu, the Customer Menu is an application that launches the browser as an embedded application with a predefined URL as parameter.
+
+
+
+ The Nokia NXX supports colour logos in addition to the traditional black and white Customer logos.
+
+
+
+ Nokia NXX supports the following types of ring tones and alert tones. The Customer may select to include tones of their own in any of the listed formats. The Customer can specify one as the default ringing tone in the General profile.
+
+
+ Start-up and shutdown animations
+
+
+
+
+ Application Menu
+
+
+
+ Themes
+
+
+
+ General
+
+
+
+
+
+ Nokia PC Internet Access a.k.a. Phone a modem
+
+
+
+ Homescreen or Active Idle customizations
+
+
+
+
+
+ Applications, music, video and other files preinstalled to device
+
+
+ Customer specific Symbian and Java applications can be pre-installed to device memory (UDA).
+
+
+
+
+
+ Maximum amount of 3 Customer specific MMS messages may be pre-installed in the Device memory.
+
+
+
+ Customer specific video clips may be pre-installed in the User Data Area or Memory card. The end user is able to delete them.
+
+
+
+ Customer can pre-load Music content in the User Data Area and/or memory card. They will be seen in Nseries Music Player. The end user is able to delete them.
+
+
+
+ Customer can pre-load images in the User Data Area and/or memory card. They will be seen in Photos application. The end user is able to delete them.
+
+
+
+ Pre-installed ringtones
+
+
+
+
+
+ Pre-installed security certificates (X.509)
+
+
+
+
+
+ Pre-installed Themes
+
+
+
+ Pre-defined Streaming Links
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/root_variant.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/root_variant.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+ Customer-independent
+ Mike Smyslov
+ 0.54
+ S60
+ 2008-12-03
+ 3.2
+ E75
+ Mike Smyslov
+
+
+ E75 Vanilla variant template for non-APAC regions filtered accordign to MDC model
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/confml/aknskins.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/confml/aknskins.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,178 @@
+
+
+
+
+ The location of the active skin. Possible values are: 0 = Phone (drives C:\ and Z:\), 2 = MMC (E:\).
+
+
+
+
+ The UID of the active skin.
+
+
+ Active color palette Uid.
+
+
+ Bitmap index of the active background image in the favourites.
+
+
+ Active background image in the favourites Uid.
+
+
+ The path name of the active background image file in Favourites.
+
+
+ Active icon set Uid.
+
+
+ Bitmap index of the active background image in the idle state.
+
+
+ The path name of the active background image file in the Idle state.
+
+
+ Active screen saver's Uid.
+
+
+ Active background image in the idle state Uid.
+
+
+ Active background image in the favourites Uid.
+
+
+ Defines the default skin of the device. If default value is used, S60 default skin is used. Given value should be in HEX.
+Note that using 16-digit PID value here has a degrading impact on device performance. 8-digit UID is thus preferred.
+
+
+ System default screen saver. Possible values are:
+DateTime (same as if the key is not set at all) - default screensaver is Date and Time screensaver.
+Text - default screensaver is Text.
+None - by default, screensaver is off.
+Defining an incorrect value will set Date and Time screensaver as default screensaver.
+Note that active screensaver is set using repository KCRUidScreenSaver with key KScreenSaverObject.
+
+
+ Active color scheme. Possible values are: 0 (blue), 1 (green), 2 (purple), 3 (red), 4 (pink), 5 (orange).
+
+
+
+
+
+
+
+
+ Available color schemes. Contains a space separated list of the supported color schemes. Values are the same as in above.
+
+
+ Highlight animation status. If 0 animations are disabled, otherwise animations are enabled.
+
+
+
+
+ Full screen wallpaper status. Value 0 means that full screen wallpaper is off, otherwise full screen wallpaper is enabled.
+
+
+
+
+ Defines wallpaper type (none/image/slide set). Value of zero means that there is no wallpaper, value of 1 means that wallpaper is single image and value of 2 means that wallpaper is defined as image slide set.
+
+
+
+
+
+ Defines the default skin of the device. If default value is used, S60 default skin is used.
+
+
+
+
+
+ Defines which operation (crop, stretch or both) should be preferred when trying to scale wallpaper to a portrait screen.
+Value of zero (0) means stretching is preferred, value of one (1) means cropping is preferred and value of two (2) means both are preferred.(3) means nhd fullscreen is preferred
+
+
+ Maximum crop factor for portrait wallpaper.
+
+
+ Maximum stretch factor for portrait wallpaper.
+
+
+ Defines which operation (crop, stretch or both) should be preferred when trying to scale wallpaper to a landscape screen.
+Value of zero (0) means stretching is preferred, value of one (1) means cropping is preferred and value of two (2) means both are preferred.(3) means nhd fullscreen is preferred
+
+
+ Maximum crop factor for landscape wallpaper.
+
+
+ Maximum stretch factor for landscape wallpaper.
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+ 1
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0.33
+ 0.23
+ 1
+ 0.131
+ 0.15
+
+
+
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ false
+ true
+ true
+ false
+ true
+ true
+ false
+
+
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/content/UI/Armi2.tpf
Binary file configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/content/UI/Armi2.tpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/content/UI/Themes/Armi.tpf
Binary file configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/content/UI/Themes/Armi.tpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/implml/aknskins_101F876F.crml
Binary file configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/implml/aknskins_101F876F.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/implml/aknskins_10282CB2.crml
Binary file configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/implml/aknskins_10282CB2.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/s60_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/s60/s60_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/test_pkg/themepackage.pkg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/test_pkg/themepackage.pkg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,65 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; File created with SkinCompiler v0.0.82
+;
+;
+; Installation file for themepackage skin
+;
+&EN
+;
+; Package header
+;
+#{"Armi"},(0xA00000EB),1,0,0,TYPE=SP
+;
+; Supports Series 60 v3.x
+; This line indicates that this installation is for the Series 60 platform v3.x
+; This line must appear _exactly_ as shown below in the sis file
+; If this line is missing or incorrect,the sis file will not be able
+; to be installed on Series 60 v3.x platforms
+;
+[0x101f7961],0,0,0,{"Series60v3.0"}
+;
+; Requires Series 60 Skins Support
+;
+(0xA00000EB),0,0,0,{"Series60SkinsSupport"}
+;
+; Requires Series 60 Scalable Skins Support
+;
+(0x10207113),0,0,0,{"Series60ScalableSkinsSupport"}
+;
+; Non-localised vendor name
+;
+:"Unknown Vendor"
+;
+; Localised vendor name
+;
+%{"Vendor-EN"}
+;
+; Files to install
+;
+IF PACKAGE(0X102032BE) ; CHECK FOR S60 3.1 STUB SIS
+"themepackage.mbm" - "!:\resource\skins\99d49b086e6097b8\themepackage.mbm"
+"themepackage.mif" - "!:\resource\skins\99d49b086e6097b8\themepackage.mif"
+ELSE
+"themepackage.mbm" - "!:\private\10207114\import\99d49b086e6097b8\themepackage.mbm"
+"themepackage.mif" - "!:\private\10207114\import\99d49b086e6097b8\themepackage.mif"
+ENDIF
+"themepackage.skn" - "!:\private\10207114\import\99d49b086e6097b8\themepackage.skn"
+;Dummy entry for the possible skin .ini file,so that it gets removed on uninstall
+"" - "!:\private\10207114\import\99d49b086e6097b8\99d49b086e6097b8.ini",FN
+;
+; End of file
+;
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/test_pkg/themepackage2.pkg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/test_pkg/themepackage2.pkg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,71 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; File created with SkinCompiler v0.0.82
+;
+;
+; Installation file for themepackage skin
+;
+&EN
+;
+; Package header
+;
+#{"MyTheme"},(0xA00000EB),1,0,0,TYPE=SP
+;
+; Supports Series 60 v3.x
+; This line indicates that this installation is for the Series 60 platform v3.x
+; This line must appear _exactly_ as shown below in the sis file
+; If this line is missing or incorrect,the sis file will not be able
+; to be installed on Series 60 v3.x platforms
+;
+[0x101f7961],0,0,0,{"Series60v3.0"}
+;
+; Requires Series 60 Skins Support
+;
+(0xA00000EB),0,0,0,{"Series60SkinsSupport"}
+;
+; Requires Series 60 Scalable Skins Support
+;
+(0x10207113),0,0,0,{"Series60ScalableSkinsSupport"}
+;
+; Non-localised vendor name
+;
+:"Unknown Vendor"
+;
+; Localised vendor name
+;
+%{"Vendor-EN"}
+;
+; Files to install
+;
+IF PACKAGE(0X102032BE) ; CHECK FOR S60 3.1 STUB SIS
+"themepackage.mbm" - "!:\resource\skins\f99553e36ea1a92f\themepackage.mbm"
+"themepackage.mif" - "!:\resource\skins\f99553e36ea1a92f\themepackage.mif"
+ELSE
+"themepackage.mbm" - "!:\private\10207114\import\f99553e36ea1a92f\themepackage.mbm"
+"themepackage.mif" - "!:\private\10207114\import\f99553e36ea1a92f\themepackage.mif"
+ENDIF
+"themepackage.skn" - "!:\private\10207114\import\f99553e36ea1a92f\themepackage.skn"
+;Dummy entry for the possible skin .ini file,so that it gets removed on uninstall
+"" - "!:\private\10207114\import\f99553e36ea1a92f\f99553e36ea1a92f.ini",FN
+;
+; Sound files
+;
+"SoundRingingTone.wma" - "!:\private\10207114\import\f99553e36ea1a92f\SoundRingingTone.wma"
+"SoundMessageAlert.wma" - "!:\private\10207114\import\f99553e36ea1a92f\SoundMessageAlert.wma"
+;
+; End of file
+;
+"transparent1.svg" - "!:\Data\Others\transparent1.svg"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+ Applications/Bundledklůk
+ Applications/Pre-installed to UDAl§l
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/content/UI/Themes/Armi.tpf
Binary file configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/content/UI/Themes/Armi.tpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/implml/theme.thememl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/implml/theme.thememl Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+
+
+
+
+ C:\Program Files\Nokia\Carbide.ui Theme Edition 3.4
+
+
+
+ CVC_PreinstalledContent/CVC_PreInstalledThemesFolder
+
+
+
+
+ CVC_Theme_ref/CVC_DefaultTheme_ref
+ KCRUidPersonalisation/KPslnActiveSkinUid
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/variant_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/variant_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/variant_view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/variant/variant_view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,660 @@
+
+
+
+ This view combines both S60 platfrom ConfML content and custom modeled ConfMLs in CVC layer
+
+ Settings for standard S60 Platform applications
+
+
+ Browser (xHTML) settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Calendar
+
+
+ Settings for Device Manager application.
+
+
+
+ Media Player
+
+
+
+
+ Voice Recorder
+
+
+ Phonebook
+
+
+ Logs
+
+
+ Camcorder
+
+
+ Clock
+
+
+
+ Positioning
+
+
+
+
+ Instant Messaging
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Settings for General Profile
+
+
+
+
+
+
+
+ Settings for Silent Profile
+
+
+
+
+ Settings for personal communication and connection methods
+
+
+ Nokia NXX has StartUp Settings application. It configures access point settings based on a SIM card�s MCC and MNC and the access point information supplied to Nokia by the network operators.
+
+
+
+
+
+ If the Customer specifies MMS settings (including Access points) in their variant then the transceiver will be able to receive MMS messages straight away after having been powered-up.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SMS Settings
+
+
+
+
+
+
+
+
+ Postcard settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Customers may choose to define one set of common settings for the e-mail client in the Messaging application of the device.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Messaging
+
+
+
+
+
+
+ Bluetooth
+
+
+
+ Streaming
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mobile TV
+
+
+ Settings for voice and video mailboxes
+
+
+
+
+
+
+
+ System settings of S60 platform
+
+
+ Accessory Profiles
+
+
+ SyncML
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Light Senso
+
+
+ Java Application Settings
+
+
+ Other
+
+
+
+
+
+
+ Telephony
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Firmware update Over The Air
+
+
+ Keypad lock settings
+
+
+ Service Messages
+
+
+ Vibra
+
+
+ Software Install
+
+
+
+
+
+
+ Settings for branding, user interface and look & feel
+
+
+ Often referred to as the Operator Menu, the Customer Menu is an application that launches the browser as an embedded application with a predefined URL as parameter.
+
+
+
+
+
+
+
+
+
+
+ The Nokia NXX supports colour logos in addition to the traditional black and white Customer logos.
+
+
+
+
+
+ Nokia NXX supports the following types of ring tones and alert tones. The Customer may select to include tones of their own in any of the listed formats. The Customer can specify one as the default ringing tone in the General profile.
+
+
+ Start-up and shutdown animations
+
+
+
+
+
+
+
+
+ Application Menu
+
+
+ Themes
+
+
+
+ General
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Nokia PC Internet Access a.k.a. Phone a modem
+
+
+
+
+
+ Homescreen or Active Idle customizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Applications, music, video and other files preinstalled to device
+
+
+ Customer specific Symbian and Java applications can be pre-installed to device memory (UDA).
+
+
+
+
+
+ Maximum amount of 3 Customer specific MMS messages may be pre-installed in the Device memory.
+
+
+
+ Customer specific video clips may be pre-installed in the User Data Area or Memory card. The end user is able to delete them.
+
+
+
+ Customer can pre-load Music content in the User Data Area and/or memory card. They will be seen in Nseries Music Player. The end user is able to delete them.
+
+
+
+ Customer can pre-load images in the User Data Area and/or memory card. They will be seen in Photos application. The end user is able to delete them.
+
+
+
+ Pre-installed ringtones
+
+
+
+
+
+ Pre-installed security certificates (X.509)
+
+
+
+
+
+ Pre-installed Themes
+
+
+
+ Pre-defined Streaming Links
+
+
+
+ Pre-defined Bookmarks
+
+
+
+ Pre-defined Contacts
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_container.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_container.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+
+import __init__
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+from themeplugin import theme_function
+from themeplugin.theme_container import ThemeContainer
+from cone.storage.filestorage import FileStorage
+
+from unittest_theme_plugin import impl_from_resource
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestThemePlugin(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = 'output'
+ pass
+
+ def tearDown(self):
+ pass
+
+
+ def test_create_themes(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"e75")))
+ config = project.get_configuration("root_variant.confml")
+ impl = impl_from_resource("variant/implml/theme.thememl", config);
+ list_tpf = impl.list_tpf_files(impl.list_active_theme, impl.list_theme_dir)
+
+ list_theme=[]
+ container = ThemeContainer(list_tpf,impl.configuration)
+ container.create_themes()
+ self.assertEquals(len(container.list_theme),2)
+ container.removeTempDirs()
+
+ def test_prepare_active_themes(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"e75")))
+ config = project.get_configuration("root_variant.confml")
+ impl = impl_from_resource("variant/implml/theme.thememl", config);
+ list_tpf = impl.list_tpf_files(impl.list_active_theme, impl.list_theme_dir)
+ container = ThemeContainer(list_tpf,impl.configuration)
+ container.create_themes()
+
+ def get_theme(lst, tpf_path):
+ for theme in lst:
+ if theme.tpf_path == tpf_path:
+ return theme
+ self.fail("Theme with tpf_path = %r not found!" % tpf_path)
+
+ self.assertEquals(len(container.list_theme), 2)
+ theme = get_theme(container.list_theme, 'variant/content/UI/Themes/Armi.tpf')
+ self.assertEquals(theme.get_setting_uids(),[])
+ self.assertEquals(theme.get_uid(), None)
+
+ container.prepare_active_themes(impl.list_active_theme)
+ theme = get_theme(container.list_theme, 's60/content/UI/Armi2.tpf')
+ self.assertEquals(theme.get_setting_uids(), ["KCRUidPersonalisation.KPslnActiveSkinUid"])
+ self.assertEquals(theme.get_uid(), "0x101FD60A")
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_function.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_function.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+
+import __init__
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+from themeplugin import maketheme
+from themeplugin import theme_function
+from cone.storage.filestorage import FileStorage
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestThemePlugin(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = 'output'
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_convert_hexa_to_decimal(self):
+ decimal = theme_function.convert_hexa_to_decimal("a5d5f19d6e6097b8")
+ self.assertEquals(decimal,"-1512705635 1851824056")
+
+ def test_find_text_in_string(self):
+ row_in_pkg_file = "\"themepackage.mbm\" - \"!:\\resource\\skins\\99d49b086e6097b8\\themepackage.mbm\""
+ start_text = "!:\\resource\\skins\\"
+ end_text = "\\"
+
+ PID_number = theme_function.find_text_in_string(row_in_pkg_file,start_text, end_text)
+ self.assertEquals(PID_number,"99d49b086e6097b8")
+
+ def test_find_text_in_file(self):
+ start_text = "!:\\resource\\skins\\"
+ end_text = "\\"
+ PID = theme_function.find_text_in_file(os.path.join(ROOT_PATH,"e75\\test_pkg\\themepackage.pkg"),start_text, end_text)
+ self.assertEquals(PID,"99d49b086e6097b8")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_plugin.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_plugin.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,76 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+
+import __init__
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+from themeplugin import maketheme
+from themeplugin import theme_function
+from cone.storage.filestorage import FileStorage
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+def impl_from_resource(resource_ref, configuration):
+ doc_root = plugin.ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
+ return maketheme.ThemeImplReader.read_impl(resource_ref, configuration, doc_root)
+
+class TestThemePlugin(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = 'output'
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_list_tpf_files(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"e75")))
+ config = project.get_configuration("root_variant.confml")
+ impl = impl_from_resource("variant/implml/theme.thememl", config);
+ t1 = impl.list_theme_dir
+ t2 = impl.list_active_theme
+ list_tpf_files = impl.list_tpf_files(impl.list_active_theme,impl.list_theme_dir)
+ self.assertEquals(sorted(list_tpf_files),
+ sorted(['variant/content/UI/Themes/Armi.tpf', 's60/content/UI/Armi2.tpf']))
+
+ def test_find_tpf_files(self):
+ project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"e75")))
+ config = project.get_configuration("root_variant.confml")
+ impl = impl_from_resource("variant/implml/theme.thememl", config)
+ tpf_paths = []
+ tpf_paths.append("UI/Themes")
+ list_tpf_files = impl.find_tpf_files(tpf_paths)
+ # The found TPF should be the one under variant/ not s60/
+ self.assertEquals(list_tpf_files, ['variant/content/UI/Themes/Armi.tpf'])
+
+ tpf_paths = []
+ tpf_paths.append("UI")
+ list_tpf_files = impl.find_tpf_files(tpf_paths)
+ self.assertEquals(list_tpf_files, ['s60/content/UI/Armi2.tpf'])
+
+ tpf_paths = []
+ tpf_paths.append("UI")
+ tpf_paths.append("UI/Themes")
+ list_tpf_files = impl.find_tpf_files(tpf_paths)
+ self.assertEquals(sorted(list_tpf_files), sorted(['variant/content/UI/Themes/Armi.tpf', 's60/content/UI/Armi2.tpf']))
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_resource.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_resource.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, shutil
+
+import __init__
+from cone.public import exceptions,plugin,api
+from cone.storage import filestorage
+from cone.confml import implml
+from themeplugin import theme_resource
+from cone.storage.filestorage import FileStorage
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestThemePlugin(unittest.TestCase):
+ def setUp(self):
+ self.curdir = os.getcwd()
+ self.output = 'output'
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_modify_resource_path(self):
+ resource = theme_resource.ThemeResource()
+ path = resource.modify_resource_path("!:\\private\\10207114\\import\\f99553e36ea1a92f\\themepackage.mbm")
+ self.assertEquals(path,"private\\10207114\\import\\f99553e36ea1a92f")
+
+ def test_parse_pkg_file(self):
+ resource = theme_resource.ThemeResource()
+ resource.parse_pkg_file(os.path.join(ROOT_PATH,"e75\\test_pkg\\themepackage2.pkg"))
+ if len(resource.list_resource) > 0:
+ filename = resource.list_resource[0].get_filename()
+ self.assertEquals(filename,"themepackage.mbm")
+ path = resource.list_resource[0].get_path()
+ self.assertEquals(path,"private\\10207114\\import\\f99553e36ea1a92f")
+ else:
+ self.assertFalse()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,275 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import unzip
+import shutil
+import logging
+from themeplugin import theme_function
+from theme_resource import ThemeResource
+from cone.storage import filestorage
+from cone.public import plugin
+
+class ThemeContainer:
+ """
+ This class provides extracts *.tpf files, convertts to *.mbm,*.pkg, ... files and set UID(PID)
+ to the setting values in the model
+ """
+
+ def __init__(self, list_tpf, configuration):
+ self.list_tpf=list_tpf
+ self.configuration=configuration
+ self.list_theme=[]
+ self.logger = logging.getLogger('cone.thememl')
+ self.carbide = None
+
+ def create_themes(self):
+ """
+ extractes tpf file to the temporary directory and creates Theme objects
+ """
+
+ for tpf in self.list_tpf:
+ logging.getLogger('cone.thememl').info("Creating temp folder for %s" % tpf)
+ theme = Theme()
+ theme.set_tpf_path(tpf)
+
+ temp_tdf = os.tempnam("Theme")
+ os.mkdir(temp_tdf)
+ temp_theme = os.path.join(temp_tdf,"__temp__")
+ os.mkdir(temp_theme)
+ theme.set_temp_theme(temp_theme)
+ theme.set_temp_tdf(temp_tdf)
+
+ self.list_theme.append(theme)
+
+
+
+ def build_theme(self, theme_version):
+ """
+ converts *.tpf files to *.mbm, *.skn, ...
+ """
+ for theme in self.list_theme:
+ self.make_theme(theme, theme_version)
+
+
+ def prepare_active_themes(self,list_active_theme):
+ """
+ goes through the active themes and sets theme in the list of all themes as active {set the name and
+ the uid number of the platform setting}
+ """
+ default_view = self.configuration.get_default_view()
+ for active_theme in list_active_theme:
+ if active_theme.get_setting_ref():
+ path=active_theme.get_setting_ref().replace("/",".")
+ setting = default_view.get_feature(path+".localPath").get_data()
+ if setting != None and setting.get_value():
+ setting_value = setting.get_value()
+ self.set_settinguid_to_theme(active_theme,setting_value)
+
+ def set_settinguid_to_theme(self,active_theme, path):
+ """
+ finds out the active theme and set the name and the uid of the platform setting
+ """
+ path = "/content/"+path
+ for theme in self.list_theme:
+ tpf_path = theme.get_tpf_path()
+
+ if tpf_path.endswith(path):
+ for setting_uid in active_theme.get_setting_uids():
+ setting_uid_value = setting_uid.replace("/",".")
+ theme.set_setting_uids(setting_uid_value)
+ theme.set_uid(active_theme.get_uid())
+
+ def set_active_PID_to_model(self):
+ """
+ finds active theme, gets PID from pkg file, convert PID from hexadecimal to decimal formal
+ and set decimal PID to the aknskins setting in the model
+ """
+ l = len (self.list_theme)
+
+
+
+ for theme in self.list_theme:
+
+ # Make sure autoconfig is the last layer
+ plugin.get_autoconfig(self.configuration)
+
+ default_view = self.configuration.get_default_view()
+
+ for setting_uid in theme.get_setting_uids():
+ aknskins_setting = default_view.get_feature(setting_uid)
+ if(theme.get_uid()):
+ uid = int(theme.get_uid(),16)
+ aknskins_setting.set_value(str(uid))
+ else:
+ PID = theme_function.find_text_in_file(os.path.join(theme.get_temp_theme(), "themepackage.pkg"), "!:\\resource\\skins\\", "\\")
+ dec_PID = theme_function.convert_hexa_to_decimal(PID)
+ if dec_PID and aknskins_setting:
+ dec_PID = theme_function.convert_hexa_to_decimal(PID)
+ aknskins_setting.set_value(str(dec_PID))
+
+ def make_theme(self, theme, theme_version):
+ """
+ converts the *tdf, *. svg files to *.mbm, *.pkg files, ...
+ The first this method extracts tpf file and then calls carbide.ui command-line
+ which converts theme.
+ """
+ output_path = theme.get_temp_theme()
+
+ if not os.path.exists(output_path):
+ os.makedirs(output_path)
+
+ storagepath = self.configuration.get_storage().get_path()
+
+ input_path = theme.get_tpf_path().replace("/","\\")
+
+ zip_output= theme.get_temp_tdf() + "\\"
+ self.unzip_tpf(theme,zip_output)
+
+ name_tdf = theme_function.get_tdf_file(zip_output)
+ name_tdf = os.path.join(name_tdf,name_tdf+".tdf")
+ input_tdf = os.path.join(zip_output,name_tdf)
+
+ command_line = "makepackage -input " + input_tdf + " -output " + output_path
+
+ if len(theme_version) != 0:
+ command_line = command_line + " -ver "+ theme_version
+
+ if theme.get_uid() != None:
+ command_line = command_line + " -uid " + theme.get_uid()
+
+ logging.getLogger('cone.thememl').info("Building theme: %s" % command_line)
+ current_dir = os.getcwd()
+ os.chdir(self.carbide)
+ os.system(command_line)
+ os.chdir(current_dir)
+
+
+ def unzip_tpf(self, theme, zip_output):
+ """
+ unzip the tpf file to output directory
+ """
+ f_storage = filestorage.FileStorage(theme.get_temp_tdf(), 'wb')
+ list=[]
+ list.append(theme.get_tpf_path())
+ storage = self.configuration.get_storage()
+ storage.export_resources(list, f_storage)
+
+ tpf_file = os.path.join(theme.get_temp_tdf(),theme.get_tpf_path().replace("/","\\"))
+
+ unzip.unzip_file_into_dir(tpf_file,zip_output)
+
+
+ def copy_resources_to_output(self,output):
+ """
+ copies *.mbm, *.skn ... to respective directories in the output directory
+ """
+ for theme in self.list_theme:
+ #gets list of path where *.mbm, *.skn, ... will be copied
+ theme_resource = ThemeResource()
+ theme_resource.parse_pkg_file(os.path.join(theme.get_temp_theme(), "themepackage.pkg"))
+
+ # copies *.mbm, *.skn ... to target paths
+ theme_resource.copy_files_from_theme(theme.get_temp_theme(), output)
+
+
+ def removeTempDirs(self):
+ """
+ remove temporary directories
+ """
+
+ for theme in self.list_theme:
+ shutil.rmtree(theme.get_temp_tdf())
+
+class Theme:
+ """
+ This class has information about theme. It contains path of tpf file and temporary directories
+ where the theme was extracted and builded
+ Ans also it contains information about the name of setting which has value as UID. The theme
+ hasn't to have this the name of setting.
+ """
+ def __init__(self):
+ #where the theme was extracted
+ self.temp_tdf = ""
+ #where the theme was builded
+ self.temp_theme = ""
+ #the path of tpf file
+ self.tpf_path = ""
+ # the name of the setting which contains UID
+ self.setting_uids = []
+ self.uids = []
+ self.uid = None
+
+ def set_tpf_path(self, tpf_path):
+ self.tpf_path = tpf_path
+
+ def get_tpf_path(self):
+ return self.tpf_path
+
+ def set_temp_tdf(self, temp_tdf):
+ self.temp_tdf = temp_tdf
+
+ def get_temp_tdf(self):
+ return self.temp_tdf
+
+ def set_temp_theme(self, temp_theme):
+ self.temp_theme = temp_theme
+
+ def get_temp_theme(self):
+ return self.temp_theme
+
+ def set_setting_uids(self, setting_uid):
+ self.setting_uids.append(setting_uid)
+
+ def get_setting_uids(self):
+ return self.setting_uids
+
+ def set_uid(self, uid):
+ self.uid = uid
+
+ def get_uid(self):
+ return self.uid
+
+class ActiveTheme(object):
+ """
+ This class performs information from thememl file.
+ It contains the name of settig (its value contains the path of tpf file) and
+ the name of setting which contains UID
+
+ """
+
+ def __init__(self):
+ self.ref_setting = None
+ self.setting_uids = []
+ self.uid = None
+
+ def set_setting_ref(self, ref_setting):
+ self.ref_setting = ref_setting
+
+ def set_setting_uids(self, setting_uid):
+ self.setting_uids.append(setting_uid)
+
+ def get_setting_ref(self):
+ return self.ref_setting
+
+ def get_setting_uids(self):
+ return self.setting_uids
+
+ def get_uid(self):
+ return self.uid
+
+ def set_uid(self,uid):
+ self.uid = uid
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_function.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_function.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,109 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from shutil import copy
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+import os
+import logging
+
+def convert_hexa_to_decimal(hexa_number):
+ """
+ convert hexa number to decimal number. Hexa number has to have 16 digitals.
+ This method split hexa number to two half and convert them to decimal format.
+ First decimal format is modified using by binary operations. This is for reasons that
+ AknSkinDescCompiler from SDK can't work with big integer numbers
+ """
+
+ if len(hexa_number) == 16:
+ hexa1 = hexa_number[0:8]
+ hexa2 = hexa_number[8:16]
+
+ decimal1 = long(hexa1,16)
+ decimal2 = long(hexa2,16)
+
+ max = 0x7fffffff
+
+ if decimal1 >= max:
+ pow = 2**31
+ num = decimal1 - pow
+ result = max ^ num
+ decimal1 = 0 - (result + 1);
+
+ decimal = str(decimal1)+" " +str(decimal2)
+ return decimal
+
+
+def get_tdf_file(path):
+ """
+ This method takes the name of the tdf file from the .project file
+ """
+
+ path = os.path.join(path,".project")
+ etree = ElementTree.parse(path)
+
+ el_name = etree.find("name")
+ if el_name != None:
+ return el_name.text
+ else:
+ logging.getLogger('cone.thememl').error("The element name is not in %s" % path)
+
+
+
+def find_text_in_file(file_path, start_text, end_text):
+ """
+ This method goes over the file and searches text which is located
+ between start_text and end_text
+ """
+
+ pkg_file=file(file_path,'r')
+ for row in pkg_file:
+ pid = find_text_in_string(row, start_text, end_text)
+ if pid != None:
+ pkg_file.close()
+ return pid
+
+ pkg_file.close()
+ return None
+
+
+def find_text_in_string(string, start_text, end_text):
+ """
+ This method return text which is located between start_text and end_text
+ """
+ index_start = string.rfind(start_text)
+ if not index_start==-1:
+ index_end = string.rfind(end_text)
+ str = string[index_start+len(start_text):index_end]
+ return str
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_resource.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_resource.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,117 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from shutil import copy
+import os
+
+class ThemeResource:
+ """
+ This class represents the records about the theme resources which are saved in *.pkg file.
+ Every record contains a filename of the resource (for example "themepackage.mbm"
+ and a path where this resource will be copied in the output directory
+ (for example "!:\private\10207114\import\99d49b086e6097b8\themepackage.mbm")
+ """
+
+ def __init__(self):
+ self.list_resource=[]
+
+ def parse_pkg_file(self,file_path):
+ """
+ parses *.pkg file and returns a array of classes ThemeResource
+ The class ThemeResource contains a name of theme resource
+ and a path where this resource will be copied in the output directory
+ """
+ pkg_file=file(file_path,'r')
+ is_found_else=False
+ row = ""
+ # for every row in pkg file
+ for row in pkg_file:
+ #if it finds tag "ELSE" then it begins load the records about the theme resources
+ if row.startswith("ELSE"):
+ is_found_else = True
+
+ if(is_found_else):
+ parts_of_row = row.split("\"")
+ #the loading record has to have 5 parts separated "\"
+ if len(parts_of_row) == 5:
+ #gets the path of the theme resource
+ path = parts_of_row[3]
+ #removes these chars "!:\" from the path of theme resource
+ path = self.modify_resource_path(path)
+ #parts_of_row[1 is the filename of the theme resource
+ resource = Resource(parts_of_row[1], path)
+ self.list_resource.append(resource)
+
+ pkg_file.close()
+
+ def copy_files_from_theme(self, source_path, output_path):
+ """
+ copies theme resources from source directory to theirs target paths
+ """
+ for resource in self.list_resource:
+ source_file = os.path.join(source_path, resource.get_filename())
+ target_dir = os.path.join(output_path, resource.get_path())
+ self.copy_files(source_file, target_dir)
+
+ def copy_files(self, source_path, target_path):
+ """
+ copy files from source to target. If the target directory doesn't exist then it is created
+ """
+ if os.path.exists(source_path) != True or os.path.isdir(source_path):
+ return
+
+ if os.path.exists(target_path) != True:
+ os.makedirs(target_path)
+ copy(source_path, target_path)
+
+ def modify_resource_path(self, path):
+ """
+ Modifies the path of them resource.
+ If the paths contains string "private" or "Data" (it says that the path is target path) then it removes
+ these chars "!:\" from the path of theme resource
+ """
+ if path.find("private") != -1 or path.find("Data") != -1:
+ if path.startswith("!:\\"):
+ index = path.rfind("\\")
+ path = path[3:index]
+
+ return path
+
+
+class Resource(object):
+ """
+ This class represents a record about the theme resource. It contains a filename of the resource
+ (for example "themepackage.mbm" and a path where this resource will be copied in the output directory
+ (for example "!:\private\10207114\import\99d49b086e6097b8\themepackage.mbm")
+ """
+
+ def __init__(self, filename,path):
+ # the name of theme resource
+ self.filename = filename
+ # the path of theme resource
+ self.path = path
+
+ def get_filename(self):
+ return self.filename
+
+ def get_path(self):
+ return self.path
+
+ def set_path(self,path):
+ self.path = path
+
+ def set_filename(self,filename):
+ self.filename = filename
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/unzip.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/unzip.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, zipfile, os, os.path
+
+def unzip_file_into_dir(file, dir):
+ if (os.path.exists(file) is not True):
+ return
+
+ if (os.path.exists(dir) is not True):
+ os.mkdir(dir, 0777)
+
+ zfobj = zipfile.ZipFile(file)
+ for name in zfobj.namelist():
+ filePath = dir + name
+ if name.endswith('/'):
+ os.mkdir(filePath)
+ else:
+ createEmtyResource(filePath)
+ outfile = open(dir+ name, 'wb')
+ outfile.write(zfobj.read(name))
+ outfile.close()
+
+def createEmtyResource(path):
+ splitdrive = os.path.splitdrive(path)
+ splitPath = os.path.split(splitdrive[1])
+
+ pathS = os.path.split(splitPath[1])
+ splited = path.split("/")
+ tempPath = ""
+ for i in range(0,len(splited)-1):
+ tempPath = tempPath+splited[i]
+ if (os.path.exists(tempPath) is not True):
+ os.mkdir(tempPath)
+ tempPath = tempPath+os.path.sep
+ if (os.path.exists(path) is not True):
+ file(path,'wt')
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/dep-eggs/readme.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/dep-eggs/readme.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+This directory contains all library dependencies needed by any of the plug-ins as egg files.
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../..'))
+assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
+
+# Import plugin_utils from the plug-in sources root
+if PLUGIN_SOURCE_ROOT not in sys.path: sys.path.append(PLUGIN_SOURCE_ROOT)
+import plugin_utils
+
+# Run integration test initialization
+plugin_utils.integration_test_init(ROOT_PATH)
+
+def collect_suite():
+ return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/export_standalone.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/export_standalone.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+from testautomation.copy_dir import copy_dir
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+def export_standalone(target_path):
+ """
+ Export any needed extra data for standalone tests.
+ @param target_path: The path where the standalone tests are being exported.
+ """
+ # Copy CRML DC test data from the CRML plug-in test data
+ dirs_to_copy = ['comp_project_1', 'comp_project_2']
+ for dir in dirs_to_copy:
+ copy_dir(source_dir = os.path.join(ROOT_PATH, '../ConeCRMLPlugin/CRMLPlugin/tests', dir),
+ target_dir = os.path.join(target_path, 'testdata/compare/crml_dc', dir),
+ dir_ignore_functions = [lambda d: d == '.svn'])
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+
+__init__.runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,810 @@
+
+
+
+
+
+Compare data - ConE
+
+
+
+
+
+
CRML Data Compatibility Report
+
+
+
+ Source:
+ root.confml
+
+
+ Target:
+ this is ignored\comp_project_2;root.confml
+
+
+
+
+
+
Modified keys/files:
+
+
+
+ File
+ Repository UID
+ Repository name
+ Key UID
+ Key name
+ Changed value
+ Old value
+ New value
+
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000001
+ Setting 1
+ type
+ int
+ real
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000002
+ Setting 2
+ backup
+ True
+ False
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000003
+ Setting 3
+ cap_wr
+ AlwaysFail
+ None
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000003
+ Setting 3
+ read_only
+ True
+ False
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000004
+ Setting 4
+ cap_wr
+ None
+ AlwaysFail
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000004
+ Setting 4
+ read_only
+ False
+ True
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000007
+ Setting 7
+ ref
+ SimpleKeys.Setting7
+ SimpleKeys.Setting7RefChanged
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000008
+ Setting 8
+ cap_rd
+ ReadDeviceData
+ ReadUserData
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000008
+ Setting 8
+ cap_wr
+ WriteDeviceData
+ WriteUserData
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000008
+ Setting 8
+ sid_rd
+ 0xAABBCCDD
+ 0x11223344
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000008
+ Setting 8
+ sid_wr
+ 0xDDCCBBAA
+ 0x44332211
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000009
+ Setting 9
+ cap_rd
+ ReadDeviceData
+ None
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000009
+ Setting 9
+ cap_wr
+ WriteDeviceData
+ None
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000009
+ Setting 9
+ sid_rd
+ 0xAABBCCDD
+ None
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x00000009
+ Setting 9
+ sid_wr
+ 0xDDCCBBAA
+ None
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001
+ Bitmask 1 (name changed)
+ cap_rd
+ ReadDeviceData
+ ReadUserData
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001
+ Bitmask 1 (name changed)
+ cap_wr
+ WriteDeviceData
+ WriteUserData
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001
+ Bitmask 1 (name changed)
+ sid_rd
+ 0xAABBCCDD
+ 0x11223344
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001
+ Bitmask 1 (name changed)
+ sid_wr
+ 0xDDCCBBAA
+ 0x44332211
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001
+ Bitmask 1 (name changed)
+ type
+ int
+ binary
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001 (bit 2)
+ Bitmask 1 (name changed)
+ ref
+ BitmaskKeys.Bit2
+ BitmaskKeys.Bit2RefChanged
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001 (bit 3)
+ Bitmask 1 (name changed)
+ invert
+ False
+ True
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ backup
+ True
+ False
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ cap_rd
+ ReadDeviceData
+ ReadUserData
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ cap_wr
+ WriteDeviceData
+ WriteUserData
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ first_index
+ 1
+ 2
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ index_bits
+ 0x00000FF0
+ 0x00001FE0
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ ref
+ KeyRanges.Seq1
+ KeyRanges.Seq1RefChanged
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ sid_rd
+ 0x11223344
+ 0xAABBCCDD
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF
+ Sequence 1 (name changed)
+ sid_wr
+ 0x44332211
+ 0xDDCCBBAA
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF (sub-key 0x00000002)
+ Sequence 1 (name changed)
+ ref
+ SubSetting2
+ SubSetting2RefChanged
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF (sub-key 0x00000002)
+ Sequence 1 (name changed)
+ type
+ int
+ real
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00002000-0x00002FFF
+ Range 2
+ backup
+ True
+ False
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00002000-0x00002FFF
+ Range 2
+ read_only
+ True
+ False
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00003000-0x00003FFF
+ Range 3
+ read_only
+ False
+ True
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000001
+ Simple key to bitmask key
+ key_type
+ simple_key
+ bitmask_key
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000002
+ Bitmask key to simple key
+ key_type
+ bitmask_key
+ simple_key
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000003
+ Bitmask key to simple key (other attrs changed also [xyz])
+ backup
+ True
+ False
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000003
+ Bitmask key to simple key (other attrs changed also [xyz])
+ cap_rd
+ ReadDeviceData
+ ReadUserData
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000003
+ Bitmask key to simple key (other attrs changed also [xyz])
+ cap_wr
+ AlwaysFail
+ WriteUserData
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000003
+ Bitmask key to simple key (other attrs changed also [xyz])
+ read_only
+ True
+ False
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000003
+ Bitmask key to simple key (other attrs changed also [xyz])
+ sid_rd
+ 0xAABBCCDD
+ 0x11223344
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000003
+ Bitmask key to simple key (other attrs changed also [xyz])
+ sid_wr
+ None
+ 0x44332211
+
+
+ Layer1/implml/00000004_key_type_changed.crml
+ 0x00000004
+ KeyTypeChanged
+ 0x00000003
+ Bitmask key to simple key (other attrs changed also [xyz])
+ type
+ int
+ binary
+
+
+ Layer1/implml/00000005_repo_attrs_changed.crml
+ 0x00000005
+ RepoAttrsChangedXyz
+ None
+
+ backup
+ True
+ False
+
+
+ Layer1/implml/00000005_repo_attrs_changed.crml
+ 0x00000005
+ RepoAttrsChangedXyz
+ None
+
+ cap_rd
+ ReadDeviceData
+ ReadUserData
+
+
+ Layer1/implml/00000005_repo_attrs_changed.crml
+ 0x00000005
+ RepoAttrsChangedXyz
+ None
+
+ cap_wr
+ WriteDeviceData
+ WriteUserData
+
+
+ Layer1/implml/00000005_repo_attrs_changed.crml
+ 0x00000005
+ RepoAttrsChangedXyz
+ None
+
+ rfs
+ True
+ False
+
+
+ Layer1/implml/00000005_repo_attrs_changed.crml
+ 0x00000005
+ RepoAttrsChangedXyz
+ None
+
+ sid_rd
+ 0x11223344
+ 0xAABBCCDD
+
+
+ Layer1/implml/00000005_repo_attrs_changed.crml
+ 0x00000005
+ RepoAttrsChangedXyz
+ None
+
+ sid_wr
+ 0x44332211
+ 0xDDCCBBAA
+
+
+ Layer1/implml/00000005_repo_attrs_changed.crml
+ 0x00000005
+ RepoAttrsChangedXyz
+ None
+
+ uid_name
+ RepoAttrsChanged
+ RepoAttrsChangedXyz
+
+
+ Layer1/implml/00000006_renamed_repo_xyz.crml
+ 0x00000006
+ RenamedRepo
+ None
+
+ file
+ Layer1/implml/00000006_renamed_repo.crml
+ Layer1/implml/00000006_renamed_repo_xyz.crml
+
+
+
+
+
+
Added keys/files:
+
+
+
+ File
+ Repository UID
+ Repository name
+ Key UID
+ Key name
+
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x20000001
+ Added setting
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001 (bit 5)
+ Bitmask 1 (name changed)
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x20000001
+ Added bitmask
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF (sub-key 0x00000005)
+ Sequence 1 (name changed)
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x20001001-0x20001FFF
+ Added range
+
+
+ Layer1/implml/20000001_added_repo.crml
+ 0x20000001
+ AddedRepo
+
+
+
+
+
+
+
+
Removed keys/files:
+
+
+
+ File
+ Repository UID
+ Repository name
+ Key UID
+ Key name
+
+
+
+ Layer1/implml/00000001_simple_keys.crml
+ 0x00000001
+ SimpleKeys
+ 0x10000001
+ Removed setting
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x00000001 (bit 4)
+ Bitmask 1
+
+
+ Layer1/implml/00000002_bitmask_keys.crml
+ 0x00000002
+ BitmaskKeys
+ 0x10000001
+ Removed bitmask
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x00001001-0x00001FFF (sub-key 0x00000004)
+ Sequence 1
+
+
+ Layer1/implml/00000003_key_ranges.crml
+ 0x00000003
+ KeyRanges
+ 0x10001001-0x10001FFF
+ Removed range
+
+
+ Layer1/implml/10000001_removed_repo.crml
+ 0x10000001
+ RemovedRepo
+
+
+
+
+
+
+
+
Duplicate repositories:
+
+
+
+ Repository UID
+ Files in source
+ Files in target
+
+
+
+ 0x30000000
+
+ Layer1/implml/30000000_duplicate_repo1_proj1.crml Layer1/implml/30000000_duplicate_repo2_proj1.crml
+
+
+ Layer1/implml/30000000_duplicate_repo1_proj2.crml Layer1/implml/30000000_duplicate_repo2_proj2.crml
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000001_simple_keys.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000001_simple_keys.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000001,Setting 1,type,int,real
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000002,Setting 2,backup,True,False
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000003,Setting 3,cap_wr,AlwaysFail,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000003,Setting 3,read_only,True,False
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000004,Setting 4,cap_wr,None,AlwaysFail
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000004,Setting 4,read_only,False,True
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000007,Setting 7,ref,SimpleKeys.Setting7,SimpleKeys.Setting7RefChanged
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,sid_rd,0xAABBCCDD,0x11223344
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,sid_wr,0xDDCCBBAA,0x44332211
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,cap_rd,ReadDeviceData,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,cap_wr,WriteDeviceData,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,sid_rd,0xAABBCCDD,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,sid_wr,0xDDCCBBAA,None
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x20000001,Added setting
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x10000001,Removed setting
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000002_bitmask_keys.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000002_bitmask_keys.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,29 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),sid_rd,0xAABBCCDD,0x11223344
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),sid_wr,0xDDCCBBAA,0x44332211
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),type,int,binary
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 2),Bitmask 1 (name changed),ref,BitmaskKeys.Bit2,BitmaskKeys.Bit2RefChanged
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 3),Bitmask 1 (name changed),invert,False,True
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 5),Bitmask 1 (name changed)
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x20000001,Added bitmask
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 4),Bitmask 1
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x10000001,Removed bitmask
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000003_key_ranges.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000003_key_ranges.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,35 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),backup,True,False
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),first_index,1,2
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),index_bits,0x00000FF0,0x00001FE0
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),ref,KeyRanges.Seq1,KeyRanges.Seq1RefChanged
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),sid_rd,0x11223344,0xAABBCCDD
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),sid_wr,0x44332211,0xDDCCBBAA
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000002),Sequence 1 (name changed),ref,SubSetting2,SubSetting2RefChanged
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000002),Sequence 1 (name changed),type,int,real
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00002000-0x00002FFF,Range 2,backup,True,False
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00002000-0x00002FFF,Range 2,read_only,True,False
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00003000-0x00003FFF,Range 3,read_only,False,True
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000005),Sequence 1 (name changed)
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x20001001-0x20001FFF,Added range
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000004),Sequence 1
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x10001001-0x10001FFF,Removed range
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000004_key_type_changed.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000004_key_type_changed.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,27 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000001,Simple key to bitmask key,key_type,simple_key,bitmask_key
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000002,Bitmask key to simple key,key_type,bitmask_key,simple_key
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),backup,True,False
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),cap_wr,AlwaysFail,WriteUserData
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),read_only,True,False
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),sid_rd,0xAABBCCDD,0x11223344
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),sid_wr,None,0x44332211
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),type,int,binary
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000005_repo_attrs_changed.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000005_repo_attrs_changed.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,backup,True,False
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,rfs,True,False
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,sid_rd,0x11223344,0xAABBCCDD
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,sid_wr,0x44332211,0xDDCCBBAA
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,uid_name,RepoAttrsChanged,RepoAttrsChangedXyz
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000006_renamed_repo.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_00000006_renamed_repo.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+Layer1/implml/00000006_renamed_repo_xyz.crml,0x00000006,RenamedRepo,None,,file,Layer1/implml/00000006_renamed_repo.crml,Layer1/implml/00000006_renamed_repo_xyz.crml
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_10000001_removed_repo.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_10000001_removed_repo.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/10000001_removed_repo.crml,0x10000001,RemovedRepo,None,
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_20000001_added_repo.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_20000001_added_repo.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/20000001_added_repo.crml,0x20000001,AddedRepo,None,
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Duplicate repositories in source:
+File,Repository UID
+
+
+Duplicate repositories in target:
+File,Repository UID
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_30000000_duplicate_repo.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_30000000_duplicate_repo.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,22 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+
+
+Duplicate repositories in source:
+File,Repository UID
+Layer1/implml/30000000_duplicate_repo1_proj1.crml
+Layer1/implml/30000000_duplicate_repo2_proj1.crml
+
+
+Duplicate repositories in target:
+File,Repository UID
+Layer1/implml/30000000_duplicate_repo1_proj2.crml
+Layer1/implml/30000000_duplicate_repo2_proj2.crml
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_all.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc_all.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,86 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000001,Setting 1,type,int,real
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000002,Setting 2,backup,True,False
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000003,Setting 3,cap_wr,AlwaysFail,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000003,Setting 3,read_only,True,False
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000004,Setting 4,cap_wr,None,AlwaysFail
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000004,Setting 4,read_only,False,True
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000007,Setting 7,ref,SimpleKeys.Setting7,SimpleKeys.Setting7RefChanged
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,sid_rd,0xAABBCCDD,0x11223344
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000008,Setting 8,sid_wr,0xDDCCBBAA,0x44332211
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,cap_rd,ReadDeviceData,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,cap_wr,WriteDeviceData,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,sid_rd,0xAABBCCDD,None
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x00000009,Setting 9,sid_wr,0xDDCCBBAA,None
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),sid_rd,0xAABBCCDD,0x11223344
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),sid_wr,0xDDCCBBAA,0x44332211
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001,Bitmask 1 (name changed),type,int,binary
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 2),Bitmask 1 (name changed),ref,BitmaskKeys.Bit2,BitmaskKeys.Bit2RefChanged
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 3),Bitmask 1 (name changed),invert,False,True
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),backup,True,False
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),first_index,1,2
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),index_bits,0x00000FF0,0x00001FE0
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),ref,KeyRanges.Seq1,KeyRanges.Seq1RefChanged
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),sid_rd,0x11223344,0xAABBCCDD
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF,Sequence 1 (name changed),sid_wr,0x44332211,0xDDCCBBAA
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000002),Sequence 1 (name changed),ref,SubSetting2,SubSetting2RefChanged
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000002),Sequence 1 (name changed),type,int,real
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00002000-0x00002FFF,Range 2,backup,True,False
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00002000-0x00002FFF,Range 2,read_only,True,False
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00003000-0x00003FFF,Range 3,read_only,False,True
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000001,Simple key to bitmask key,key_type,simple_key,bitmask_key
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000002,Bitmask key to simple key,key_type,bitmask_key,simple_key
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),backup,True,False
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),cap_wr,AlwaysFail,WriteUserData
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),read_only,True,False
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),sid_rd,0xAABBCCDD,0x11223344
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),sid_wr,None,0x44332211
+Layer1/implml/00000004_key_type_changed.crml,0x00000004,KeyTypeChanged,0x00000003,Bitmask key to simple key (other attrs changed also [xyz]),type,int,binary
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,backup,True,False
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,cap_rd,ReadDeviceData,ReadUserData
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,cap_wr,WriteDeviceData,WriteUserData
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,rfs,True,False
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,sid_rd,0x11223344,0xAABBCCDD
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,sid_wr,0x44332211,0xDDCCBBAA
+Layer1/implml/00000005_repo_attrs_changed.crml,0x00000005,RepoAttrsChangedXyz,None,,uid_name,RepoAttrsChanged,RepoAttrsChangedXyz
+Layer1/implml/00000006_renamed_repo_xyz.crml,0x00000006,RenamedRepo,None,,file,Layer1/implml/00000006_renamed_repo.crml,Layer1/implml/00000006_renamed_repo_xyz.crml
+
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x20000001,Added setting
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 5),Bitmask 1 (name changed)
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x20000001,Added bitmask
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000005),Sequence 1 (name changed)
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x20001001-0x20001FFF,Added range
+Layer1/implml/20000001_added_repo.crml,0x20000001,AddedRepo,None,
+
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+Layer1/implml/00000001_simple_keys.crml,0x00000001,SimpleKeys,0x10000001,Removed setting
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x00000001 (bit 4),Bitmask 1
+Layer1/implml/00000002_bitmask_keys.crml,0x00000002,BitmaskKeys,0x10000001,Removed bitmask
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x00001001-0x00001FFF (sub-key 0x00000004),Sequence 1
+Layer1/implml/00000003_key_ranges.crml,0x00000003,KeyRanges,0x10001001-0x10001FFF,Removed range
+Layer1/implml/10000001_removed_repo.crml,0x10000001,RemovedRepo,None,
+
+
+Duplicate repositories in source:
+File,Repository UID
+Layer1/implml/30000000_duplicate_repo1_proj1.crml
+Layer1/implml/30000000_duplicate_repo2_proj1.crml
+
+
+Duplicate repositories in target:
+File,Repository UID
+Layer1/implml/30000000_duplicate_repo1_proj2.crml
+Layer1/implml/30000000_duplicate_repo2_proj2.crml
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/SVGTBinEncode.exe
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/SVGTBinEncode.exe has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/ThirdPartyBitmap.pal
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/ThirdPartyBitmap.pal Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,256 @@
+0x00000000
+0x00CCFFFF
+0x0099FFFF
+0x0066FFFF
+0x0033FFFF
+0x0000FFFF
+0x00FFCCFF
+0x00CCCCFF
+0x0099CCFF
+0x0066CCFF
+0x0033CCFF
+0x0000CCFF
+0x00FF99FF
+0x00CC99FF
+0x009999FF
+0x006699FF
+0x003399FF
+0x000099FF
+0x00FF66FF
+0x00CC66FF
+0x009966FF
+0x006666FF
+0x003366FF
+0x000066FF
+0x00FF33FF
+0x00CC33FF
+0x009933FF
+0x006633FF
+0x003333FF
+0x000033FF
+0x00FF00FF
+0x00CC00FF
+0x009900FF
+0x006600FF
+0x003300FF
+0x000000FF
+0x00FFFFCC
+0x00CCFFCC
+0x0099FFCC
+0x0066FFCC
+0x0033FFCC
+0x0000FFCC
+0x00FFCCCC
+0x00CCCCCC
+0x0099CCCC
+0x0066CCCC
+0x0033CCCC
+0x0000CCCC
+0x00FF99CC
+0x00CC99CC
+0x009999CC
+0x006699CC
+0x003399CC
+0x000099CC
+0x00FF66CC
+0x00CC66CC
+0x009966CC
+0x006666CC
+0x003366CC
+0x000066CC
+0x00FF33CC
+0x00CC33CC
+0x009933CC
+0x006633CC
+0x003333CC
+0x000033CC
+0x00FF00CC
+0x00CC00CC
+0x009900CC
+0x006600CC
+0x003300CC
+0x000000CC
+0x00FFFF99
+0x00CCFF99
+0x0099FF99
+0x0066FF99
+0x0033FF99
+0x0000FF99
+0x00FFCC99
+0x00CCCC99
+0x0099CC99
+0x0066CC99
+0x0033CC99
+0x0000CC99
+0x00FF9999
+0x00CC9999
+0x00999999
+0x00669999
+0x00339999
+0x00009999
+0x00FF6699
+0x00CC6699
+0x00996699
+0x00666699
+0x00336699
+0x00006699
+0x00FF3399
+0x00CC3399
+0x00993399
+0x00663399
+0x00333399
+0x00003399
+0x00FF0099
+0x00CC0099
+0x00990099
+0x00660099
+0x00330099
+0x00000099
+0x00FFFF66
+0x00CCFF66
+0x0099FF66
+0x0066FF66
+0x0033FF66
+0x0000FF66
+0x00FFCC66
+0x00CCCC66
+0x0099CC66
+0x0066CC66
+0x0033CC66
+0x0000CC66
+0x00FF9966
+0x00CC9966
+0x00999966
+0x00669966
+0x00339966
+0x00009966
+0x00FF6666
+0x00CC6666
+0x00996666
+0x00666666
+0x00336666
+0x00006666
+0x00FF3366
+0x00CC3366
+0x00993366
+0x00663366
+0x00333366
+0x00003366
+0x00FF0066
+0x00CC0066
+0x00990066
+0x00660066
+0x00330066
+0x00000066
+0x00FFFF33
+0x00CCFF33
+0x0099FF33
+0x0066FF33
+0x0033FF33
+0x0000FF33
+0x00FFCC33
+0x00CCCC33
+0x0099CC33
+0x0066CC33
+0x0033CC33
+0x0000CC33
+0x00FF9933
+0x00CC9933
+0x00999933
+0x00669933
+0x00339933
+0x00009933
+0x00FF6633
+0x00CC6633
+0x00996633
+0x00666633
+0x00336633
+0x00006633
+0x00FF3333
+0x00CC3333
+0x00993333
+0x00663333
+0x00333333
+0x00003333
+0x00FF0033
+0x00CC0033
+0x00990033
+0x00660033
+0x00330033
+0x00000033
+0x00FFFF00
+0x00CCFF00
+0x0099FF00
+0x0066FF00
+0x0033FF00
+0x0000FF00
+0x00FFCC00
+0x00CCCC00
+0x0099CC00
+0x0066CC00
+0x0033CC00
+0x0000CC00
+0x00FF9900
+0x00CC9900
+0x00999900
+0x00669900
+0x00339900
+0x00009900
+0x00FF6600
+0x00CC6600
+0x00996600
+0x00666600
+0x00336600
+0x00006600
+0x00FF3300
+0x00CC3300
+0x00993300
+0x00663300
+0x00333300
+0x00003300
+0x00FF0000
+0x00CC0000
+0x00990000
+0x00660000
+0x00330000
+0x00000000
+0x00EEEEEE
+0x00DDDDDD
+0x00BBBBBB
+0x00AAAAAA
+0x00888888
+0x00777777
+0x00555555
+0x00444444
+0x00222222
+0x00111111
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00000000
+0x00FFFFFF
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/bmconv.exe
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/bmconv.exe has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/mifconv.exe
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/mifconv.exe has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/xerces-c_2_6.dll
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/imageplugin_bin/xerces-c_2_6.dll has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/mock_carbide_ui/makepackage.bat
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/mock_carbide_ui/makepackage.bat Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+@echo off
+rem
+rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+rem All rights reserved.
+rem This component and the accompanying materials are made available
+rem under the terms of "Eclipse Public License v1.0"
+rem which accompanies this distribution, and is available
+rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+rem
+rem Initial Contributors:
+rem Nokia Corporation - initial contribution.
+rem
+rem Contributors:
+rem
+rem Description:
+rem
+
+python %~dp0\makepackage.py %*
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/mock_carbide_ui/makepackage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/mock_carbide_ui/makepackage.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, random
+
+output_dir = ''
+uid = None
+
+for i, item in enumerate(sys.argv):
+ if item == '-output' and i + 1 < len(sys.argv):
+ output_dir = sys.argv[i + 1]
+ elif item == '-uid' and i + 1 < len(sys.argv):
+ uid = sys.argv[i + 1]
+
+if uid is None:
+ uid = "%016x" % random.getrandbits(64)
+else:
+ if uid.lower().startswith('0x'):
+ uid = uid[2:]
+
+#print "uid = %s" % uid
+
+
+def write_file(file_path, data):
+ dir = os.path.dirname(file_path)
+ if dir != '' and not os.path.exists(dir):
+ os.makedirs(dir)
+
+ f = open(file_path, "wb")
+ try: f.write(data)
+ finally: f.close()
+
+write_file(os.path.join(output_dir, 'themepackage.mbm'), 'xyz')
+write_file(os.path.join(output_dir, 'themepackage.mif'), 'zyx')
+write_file(os.path.join(output_dir, 'themepackage.skn'), 'foo')
+
+pkg_data = r"""
+IF PACKAGE(0X102032BE) ; CHECK FOR S60 3.1 STUB SIS
+"themepackage.mbm" - "!:\resource\skins\%(uid)s\themepackage.mbm"
+"themepackage.mif" - "!:\resource\skins\%(uid)s\themepackage.mif"
+ELSE
+"themepackage.mbm" - "!:\private\10207114\import\%(uid)s\themepackage.mbm"
+"themepackage.mif" - "!:\private\10207114\import\%(uid)s\themepackage.mif"
+ENDIF
+"themepackage.skn" - "!:\private\10207114\import\%(uid)s\themepackage.skn"
+;Dummy entry for the possible skin .ini file,so that it gets removed on uninstall
+"" - "!:\private\10207114\import\%(uid)s\%(uid)s.ini",FN
+""" % {'uid': uid}
+
+write_file(os.path.join(output_dir, 'themepackage.pkg'), pkg_data)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/.project
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/.project Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+ test_project
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerBuilder
+
+
+
+
+ com.nokia.s60ct.build.CenRepBuilder
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerNature
+ com.nokia.s60ct.build.CenRepNature
+ com.nokia.s60ct.build.CenRepNature
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/basic_setting_types_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/basic_setting_types_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+
+
+
+ Feature with basic setting types (ConfML v2.0)
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/bitmask_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/bitmask_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+
+
+
+ Feature with bitmask flags
+
+ A boolean setting for bit 0
+
+
+ A boolean setting for bit 1
+
+
+ A boolean setting for bit 2
+
+
+ A boolean setting for bit 3
+
+
+ A boolean setting for bit 4
+
+
+ A boolean setting for bit 5
+
+
+
+
+ true
+ false
+ true
+ false
+ true
+ false
+
+
+
+
+
+ false
+ true
+ false
+ true
+ false
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/feature2.confml
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/file_folder_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/file_folder_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+
+
+
+ Feature with file and folder setting types
+
+ A folder setting
+
+
+
+
+ A file setting
+
+
+
+
+
+
+
+ default_folder
+ default_target_folder/
+
+
+ default_file.txt
+ default_target_folder/default_file_renamed.txt
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/hcr_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/hcr_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+ 123456789
+ true
+ Some testing text
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/sequence_setting_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/sequence_setting_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,71 @@
+
+
+
+ Feature with a sequence setting (ConfML v2.0)
+
+ A sequence setting
+
+ A folder sub-setting
+
+
+
+
+ A real sub-setting
+
+
+ A file sub-setting
+
+
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ false
+ 1
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/sound_file_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/sound_file_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+ Z:\\data\\sounds\\some_sound.mp3
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/theme_uids.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/theme_uids.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,23 @@
+
+
+
+ Feature for storing theme UIDs
+
+
+
+
+
+
+
+
+
+
+ 0x00000000
+ 0x00000000
+ 0x00000000
+
+ 0x00000000
+ 0x00000000
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/time_types_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/confml/time_types_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,26 @@
+
+
+
+ Feature with date-time etc. setting types
+
+ A date setting
+
+
+ A time setting
+
+
+ A date-time setting
+
+
+ A duration setting
+
+
+
+
+ 2009-02-02
+ 07:30:15
+ 2009-02-02-07:00:00
+ P5Y4M3DT12H25M15S
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/bitmask_test_12341002.crml
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/bitmask_test_12341002.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature1_12341000.crml
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature1_12341000.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature1_12341001.crml
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature1_12341001.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature1_sequence.gcfml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature1_sequence.gcfml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ , , , , , ,
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature2_ABCD0000.crml
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/feature2_ABCD0000.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/hcr_test.hcrml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/hcr_test.hcrml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/sound_file_test_10000000.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/sound_file_test_10000000.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/theme_uids_20000000.crml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/theme_uids_20000000.crml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/time_types_test_12341003.crml
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/implml/time_types_test_12341003.crml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/base/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/confml/custom.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/confml/custom.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,73 @@
+
+
+
+ Settings for configuring the base layer's settings via rules and other implementation files on this layer
+
+
+ Sets whether the feature BitmaskTest is configured with pre-defined values
+
+
+
+ The folder used for generating an .mbm file
+
+
+
+
+
+ The folder used for generating a .mif file
+
+
+
+
+
+ Sound file.
+
+
+
+
+
+ Sound folder.
+
+
+
+
+
+
+
+ Folder containing themes
+
+
+
+
+
+ TPF file for theme 1
+
+
+
+
+
+ TPF file for theme 2
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+ default.mp3
+
+
+
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/confml/view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/confml/view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+
+
+
+ Testing view located on layer 1.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/bmp_animation.imageml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/bmp_animation.imageml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/configure_bitmask.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/configure_bitmask.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+CustomConfSettings.ConfigureBitmask configures
+ BitmaskTest.Bit0 = '0' and
+ BitmaskTest.Bit1 = '1' and
+ BitmaskTest.Bit2 = '0' and
+ BitmaskTest.Bit3 = '1' and
+ BitmaskTest.Bit4 = '0' and
+ BitmaskTest.Bit5 = '1'
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/sound.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/sound.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+ CustomConfSettings.SoundFile.localPath configures SoundFileTest.SoundFilePath = SoundFileTest.SoundFilePath filenamejoin CustomConfSettings.SoundFile.localPath
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/sound2.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/sound2.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/svg_animation.imageml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/svg_animation.imageml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/themes.thememl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/themes.thememl Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+
+
+
+ mock_carbide_ui
+
+
+
+
+ CustomConfSettings/Theme1File
+ ThemeUids/Theme1Uid1
+ ThemeUids/Theme1Uid2
+ ThemeUids/Theme1Uid3
+
+
+
+ CustomConfSettings/Theme2File
+ ThemeUids/Theme2Uid1
+ ThemeUids/Theme2Uid2
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+ True configures Feature1.StringSetting = Feature1.StringSetting + " " + BasicSettingTypesTest.StringSetting + u" カタカナ"
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+
+
+
+
+ 555
+ カタカナ <&>
+
+
+ true
+ animation
+ svg_animation
+ local_sounds/test.mp3
+ sound_folder
+ test2.mp3
+
+ themes/mock_theme_1.tpf
+ themes/mock_theme_2.tpf
+
+
+
+
+ seq/default_folder
+ 10.10
+ seq/default_file.txt
+ 120
+ <&カタカナ>
+ true
+ 2
+
+
+
+
+
+ 1.5
+ 256
+ test
+ true
+ 1
+
+
+
+
+ 1234
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame01.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame01.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame02.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame02.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame03.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame03.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame04.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame04.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame05.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame05.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame06.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame06.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame07.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame07.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame08.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame08.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame09.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame09.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame10.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame10.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame11.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame11.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame12.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame12.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame13.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame13.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame14.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame14.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame15.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame15.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame16.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame16.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame17.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame17.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame18.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame18.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame19.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame19.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame20.bmp
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/animation/frame20.bmp has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/local_sounds/test.mp3
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/local_sounds/test.mp3 has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_01.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_01.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_02.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_02.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_03.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_03.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_04.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_04.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_05.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_05.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_06.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_06.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_07.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_07.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_08.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_08.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_09.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_09.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_10.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/svg_animation/wait_animation_10.svg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/themes/mock_theme_1.tpf
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/themes/mock_theme_1.tpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/themes/mock_theme_2.tpf
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/themes/mock_theme_2.tpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/themes/mock_theme_3.tpf
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/content/themes/mock_theme_3.tpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/data/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/unittest_crml_dc.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/unittest_crml_dc.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,189 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+import sys, os, shutil, unittest
+import __init__
+from testautomation.base_testcase import BaseTestCase
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+TEMP_DIR = os.path.normpath(os.path.join(ROOT_PATH, 'temp/crml_dc'))
+
+if sys.platform == "win32":
+ CONE_SCRIPT = "cone.cmd"
+else:
+ CONE_SCRIPT = "cone.sh"
+
+def get_cmd(action='compare'):
+ """Return the command used to run the ConE sub-action"""
+ if 'CONE_PATH' in os.environ:
+ CONE_CMD = os.path.join(os.environ['CONE_PATH'], CONE_SCRIPT)
+ if not os.path.exists(CONE_CMD):
+ raise RuntimeError("'%s' does not exist!" % CONE_CMD)
+ return '"%s" %s' % (CONE_CMD, action)
+ else:
+ SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+ assert os.path.split(SOURCE_ROOT)[1] == 'source'
+ cmd = 'python "%s" %s' % (os.path.normpath(os.path.join(SOURCE_ROOT, 'scripts/cone_tool.py')), action)
+ return cmd
+
+def get_crml_dc_testdata_dir():
+ # If running from the working copy
+ dir1 = os.path.normpath(os.path.join(ROOT_PATH, '../ConeCRMLPlugin/CRMLPlugin/tests'))
+ if os.path.isdir(dir1): return dir1
+
+ # If running from standalone
+ dir2 = os.path.normpath(os.path.join(ROOT_PATH, 'testdata/compare/crml_dc'))
+ if os.path.isdir(dir2): return dir2
+
+ raise RuntimeError("CRML DC test data found neither in '%s' nor '%s'!" % (dir1, dir2))
+
+
+class TestCompareAction(BaseTestCase):
+
+ def setUp(self):
+ if not os.path.exists(TEMP_DIR):
+ os.makedirs(TEMP_DIR)
+
+ def _run_crml_dc_test(self, crml_file_name_without_extension, do_filtering=True):
+ testdata_dir = get_crml_dc_testdata_dir()
+ report_file = 'crml_dc_%s.csv' % crml_file_name_without_extension
+ if do_filtering:
+ impl_filter = '%s' % crml_file_name_without_extension
+ else:
+ impl_filter = '.*'
+ self._run_comparison_test(
+ source_project = os.path.join(testdata_dir, 'comp_project_1'),
+ source_conf = 'root.confml',
+ target_project = os.path.join(testdata_dir, 'comp_project_2'),
+ target_conf = 'root.confml',
+ report_type = 'crml_dc_csv',
+ report_file = report_file,
+ impl_filter = impl_filter,
+ check_against_expected_output = True)
+
+ def test_crml_dc_00000001_simple_keys(self): self._run_crml_dc_test('00000001_simple_keys')
+ def test_crml_dc_00000002_bitmask_keys(self): self._run_crml_dc_test('00000002_bitmask_keys')
+ def test_crml_dc_00000003_key_ranges(self): self._run_crml_dc_test('00000003_key_ranges')
+ def test_crml_dc_00000004_key_type_changed(self): self._run_crml_dc_test('00000004_key_type_changed')
+ def test_crml_dc_00000005_repo_attrs_changed(self): self._run_crml_dc_test('00000005_repo_attrs_changed')
+ def test_crml_dc_10000001_removed_repo(self): self._run_crml_dc_test('10000001_removed_repo')
+ def test_crml_dc_20000001_added_repo(self): self._run_crml_dc_test('20000001_added_repo')
+ def test_crml_dc_00000006_renamed_repo(self): self._run_crml_dc_test('00000006_renamed_repo')
+ def test_crml_dc_30000000_duplicate_repo(self): self._run_crml_dc_test('30000000_duplicate_repo')
+ def test_crml_dc_all(self): self._run_crml_dc_test('all', do_filtering=False)
+
+ def test_crml_dc_html_report(self):
+ testdata_dir = get_crml_dc_testdata_dir()
+
+ # Ignore the portion of the data where the path to the target is shown
+ ignore_patterns = [r'\s*Target: \s*.*[\\,/]comp_project_2;root.confml ']
+
+ self._run_comparison_test(
+ source_project = os.path.join(testdata_dir, 'comp_project_1'),
+ source_conf = 'root.confml',
+ target_project = os.path.join(testdata_dir, 'comp_project_2'),
+ target_conf = 'root.confml',
+ report_type = 'crml_dc',
+ report_file = 'crml_dc.html',
+ check_against_expected_output = True,
+ data_ignore_patterns = ignore_patterns)
+
+ def _run_comparison_test(self, **kwargs):
+ """
+ Run comparison test.
+
+ @param source_project: The source project, relative to the test data directory or an
+ absolute path.
+ @param source_conf: The source configuration.
+ @param target_project: The target project, relative to the test data directory
+ If not given or None, the source project will be used also for this.
+ @param target_conf: The target configuration.
+ @param template: The template file used for the report, relative to the test data directory.
+ @param report_type: The report type. Should not be used with the 'template' parameter.
+ @param report_file: The location where the report is written. This will also be used as
+ the name of the expected report file against which the actual report is checked.
+ @param impl_filter: Implementation filter to use.
+ @param check_against_expected_output: If True, the actual report is checked against an
+ expected file with the same name. Otherwise it is just checked that the output
+ file has been created and it contains something.
+ @param data_ignore_patterns: List of regular expression patterns for ignoring some portions
+ of the data when checking against expected output. The patterns are used to remove
+ data portions before doing the actual comparison.
+ """
+ # Get parameters
+ # ---------------
+ def get_project_absdir(project_dir):
+ if os.path.isabs(project_dir):
+ return project_dir
+ else:
+ return os.path.normpath(os.path.join(TESTDATA_DIR, project_dir))
+
+ source_conf = kwargs['source_conf']
+ target_conf = kwargs['target_conf']
+ source_project = get_project_absdir(kwargs['source_project'])
+ target_project = kwargs.get('target_project', None)
+
+ if target_project != None:
+ target_project = get_project_absdir(target_project)
+ target_conf = target_project + ';' + target_conf
+
+ template = kwargs.get('template', None)
+ report_type = kwargs.get('report_type', None)
+ if template and report_type:
+ raise ValueError("Both 'template' and 'report_type' parameters given")
+ elif not template and not report_type:
+ raise ValueError("Neither 'template' not 'report_type' parameter given")
+ elif template:
+ template = os.path.normpath(os.path.join(TESTDATA_DIR, template))
+
+ report_file = kwargs['report_file']
+ check_against_expected_output = kwargs['check_against_expected_output']
+ actual_report = os.path.normpath(os.path.join(TEMP_DIR, report_file))
+
+ impl_filter = kwargs.get('impl_filter', None)
+
+
+ # Generate output
+ # ----------------
+ if report_type:
+ command = '%s -p "%s" -s "%s" -t "%s" --report-type "%s" --report "%s"' \
+ % (get_cmd(), source_project, source_conf, target_conf, report_type, actual_report)
+ else:
+ command = '%s -p "%s" -s "%s" -t "%s" --template "%s" --report "%s"' \
+ % (get_cmd(), source_project, source_conf, target_conf, template, actual_report)
+
+ if impl_filter:
+ command += ' --impl-filter "%s"' % impl_filter
+
+ self.remove_if_exists(actual_report)
+ self.run_command(command)
+
+
+ # Check output
+ # -------------
+ if check_against_expected_output:
+ expected_report = os.path.normpath(os.path.join(ROOT_PATH, 'testdata/crml_dc_expected', report_file))
+ ignore_patterns = kwargs.get('data_ignore_patterns', [])
+ self.assert_file_contents_equal(expected_report, actual_report, ignore_patterns)
+ else:
+ self.assert_exists_and_contains_something(actual_report)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/integration-test/unittest_generate.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/unittest_generate.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,155 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, shutil, unittest
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation import zip_dir
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+if sys.platform == "win32":
+ CONE_SCRIPT = "cone.cmd"
+else:
+ CONE_SCRIPT = "cone.sh"
+
+def get_cmd(action='generate'):
+ """Return the command used to run the ConE sub-action"""
+ if 'CONE_PATH' in os.environ:
+ CONE_CMD = os.path.join(os.environ['CONE_PATH'], CONE_SCRIPT)
+ if not os.path.exists(CONE_CMD):
+ raise RuntimeError("'%s' does not exist!" % CONE_CMD)
+ return '"%s" %s' % (CONE_CMD, action)
+ else:
+ SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+ assert os.path.split(SOURCE_ROOT)[1] == 'source'
+ cmd = 'python "%s" %s' % (os.path.normpath(os.path.join(SOURCE_ROOT, 'scripts/cone_tool.py')), action)
+ return cmd
+
+class TestSymbianGenerateAllImplsOnLastLayer(BaseTestCase):
+
+ def _prepare_workdir(self, workdir):
+ workdir = os.path.join(ROOT_PATH, workdir)
+ self.recreate_dir(workdir)
+
+ # Get the binaries needed for ImageML to work
+ bin_target_dir = os.path.join(workdir, "bin")
+ self.recreate_dir(bin_target_dir)
+ bin_source_dir = os.path.join(ROOT_PATH, "testdata/generate/imageplugin_bin")
+ for name in os.listdir(bin_source_dir):
+ source_path = os.path.join(bin_source_dir, name)
+ target_path = os.path.join(bin_target_dir, name)
+ if os.path.isfile(source_path):
+ shutil.copy2(source_path, target_path)
+
+ # Create the mock carbide.ui directory
+ target_dir = os.path.join(workdir, "mock_carbide_ui")
+ self.recreate_dir(target_dir)
+ def copy_file(file_name):
+ source_file = os.path.join(ROOT_PATH, "testdata/generate/mock_carbide_ui", file_name)
+ target_file = os.path.join(target_dir, file_name)
+ shutil.copy2(source_file, target_file)
+ copy_file('makepackage.bat')
+ copy_file('makepackage.py')
+
+ return workdir
+
+ def test_generate_all_impls_on_last_layer_on_file_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
+ self.assert_exists_and_contains_something(project_dir)
+ self._run_test_generate_all_impls_on_last_layer('temp/gen_ll1', project_dir)
+
+ def test_generate_all_impls_on_last_layer_on_zip_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
+ self.assert_exists_and_contains_something(project_dir)
+
+ project_zip = os.path.join(ROOT_PATH, "temp/generation_test_project.zip")
+ self.remove_if_exists(project_zip)
+ zip_dir.zip_dir(project_dir, project_zip, [zip_dir.SVN_IGNORE_PATTERN])
+ self.assert_exists_and_contains_something(project_zip)
+
+ self._run_test_generate_all_impls_on_last_layer('temp/gen_ll2', project_zip)
+
+ def _run_test_generate_all_impls_on_last_layer(self, workdir, project):
+ # Create a temp workdir and go there to run the test
+ orig_workdir = os.getcwd()
+ workdir = self._prepare_workdir(workdir)
+ os.chdir(workdir)
+
+ try:
+ # Run the generation command
+ cmd = '%s -p "%s" --output output --layer -1 --add-setting-file imaker_variantdir.cfg' % (get_cmd(), project)
+ self.run_command(cmd)
+
+ # Check that all expected output files are generated
+ def check(path):
+ self.assert_exists_and_contains_something("output/" + path)
+
+ try:
+ check("content/animations/anim1.mbm")
+ check("content/animations/anim2.mif")
+ except AssertionError:
+ if ' ' in ROOT_PATH:
+ self.fail("Known bug (#177)")
+ else:
+ raise
+
+ check("content/data/sounds/test.mp3")
+ check("content/data/sequence_setting_test.txt")
+ check("content/private/10202BE9/10000000.txt")
+ check("content/private/10202BE9/12341001.txt")
+ check("content/private/10202BE9/12341002.txt")
+ check("content/private/10202BE9/20000000.txt")
+ check("content/sound_folder/test2.mp3")
+ check("hcr_test.h")
+ check("content/private/10207114/import/12340001/themepackage.mbm")
+ check("content/private/10207114/import/12340001/themepackage.mif")
+ check("content/private/10207114/import/12340001/themepackage.skn")
+
+ # Check that files that should not have been generated are not
+ def check_not_gen(path):
+ self.assertFalse(os.path.exists("output/" + path),
+ "'%s' was generated when it should not have been!" % path)
+ check_not_gen("content/private/10202BE9/ABCD0000.txt")
+ check_not_gen("content/private/10202BE9/12341000.txt")
+
+ # Check that the data has been generated correctly
+ self.assert_file_contains(
+ "output/content/private/10202BE9/12341002.txt",
+ "0x1 int 42 0 cap_rd=alwayspass cap_wr=WriteDeviceData",
+ encoding='utf-16')
+ self.assert_file_contains(
+ "output/content/private/10202BE9/10000000.txt",
+ r'0x1 string "Z:\\data\\sounds\\test.mp3" 0 cap_rd=alwayspass cap_wr=WriteDeviceData',
+ encoding='utf-16')
+ self.assert_file_contains(
+ "output/content/private/10202BE9/12341001.txt",
+ u'0x1 string "default string カタカナ <&> カタカナ" 0 cap_rd=alwayspass cap_wr=WriteDeviceData',
+ encoding='utf-16')
+ self.assert_file_contains(
+ "output/content/private/10202BE9/20000000.txt",
+ ['0x11 string "305397761" 0',
+ '0x12 string "305397761" 0',
+ '0x13 string "305397761" 0',
+ '0x21 string "305397762" 0',
+ '0x22 string "305397762" 0'],
+ encoding='utf-16')
+ finally:
+ os.chdir(orig_workdir)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/plugins/symbian/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, re, unittest
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
+assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
+if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
+import plugin_utils
+
+if __name__ == "__main__":
+ # Collect a list of plug-in source paths and plug-in module names
+ paths_and_modnames = plugin_utils.find_plugin_sources(ROOT_PATH)
+ # Create a test suite from them
+ suite = plugin_utils.collect_suite_from_source_list(paths_and_modnames)
+ # Run the suite
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,158 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Script for running all ConE unit tests (cone, plug-ins and scripts).
+#
+
+import os, sys, re, imp
+import unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+# For module 'testautomation'
+sys.path.append(os.path.join(ROOT_PATH, 'testautomation'))
+
+from testautomation import testcli
+import cone
+import cone.public.plugin
+
+def _load_module(path):
+ if not path.endswith('.py'):
+ raise ValueError("Given parameter ('%s') is not a .py file" % path)
+
+ dir = os.path.dirname(path)
+ sys.path.insert(0, dir)
+ try:
+ modname = path.replace('.', '_')
+ return imp.load_source(modname, path)
+ finally:
+ del sys.path[0]
+ # Since the module name __init__ is needed in many places,
+ # but its contents may differ, remove it from sys.modules
+ # in order to force reloading every time
+ if '__init__' in sys.modules:
+ del sys.modules['__init__']
+
+def _collect_unittest_suite_from_file(file_path):
+ suite = unittest.TestSuite()
+ module = _load_module(file_path)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+
+
+def _find_unittest_files(path, recursive=True):
+ """
+ Find all unittest_*.py files under the given directory.
+ """
+ pattern = re.compile(r'^unittest_.*\.py$')
+ unittest_files = []
+ if recursive:
+ for root, dirs, files in os.walk(path, topdown=True):
+ for filename in files:
+ if pattern.match(filename) != None:
+ filepath = os.path.abspath(os.path.join(root, filename))
+ unittest_files.append(filepath)
+ else:
+ for filename in os.listdir(path):
+ if pattern.match(filename) != None:
+ filepath = os.path.abspath(os.path.join(path, filename))
+ unittest_files.append(filepath)
+
+ return unittest_files
+
+def _collect_unittest_suite_from_path(path, recursive=True):
+ """
+ Collect a test suite containing all test cases loaded from
+ unittest_*.py files in the given directory.
+ """
+ path = os.path.abspath(path)
+
+ # Collect the list of .py files containing unit tests
+ unittest_files = _find_unittest_files(path, recursive)
+
+ # Load the files as modules and load tests from them
+ suite = unittest.TestSuite()
+ for file in unittest_files:
+ module = _load_module(file)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+
+def _collect_suite():
+ def get_suite(path):
+ return _collect_unittest_suite_from_path(os.path.join(ROOT_PATH, path))
+ def get_suite_from_file(file_path):
+ return _collect_unittest_suite_from_file(os.path.join(ROOT_PATH, file_path))
+
+ suite = unittest.TestSuite()
+ suite.addTests(get_suite('cone'))
+ suite.addTests(get_suite('scripts/tests'))
+ suite.addTests(get_suite('plugins'))
+ suite.addTests(get_suite('testautomation'))
+
+ # Tests can also be loaded from a file:
+ #suite.addTests(get_suite_from_file('cone/public/tests/unittest_rules_on_configuration.py'))
+
+
+ # Force-reload all ConE plug-in reader classes, since the __init__.py
+ # files in the imported test cases have added plug-in sources to sys.path
+ cone.public.plugin.ImplFactory.force_reload_reader_classes()
+
+ return suite
+
+def _run_without_nose():
+ suite = _collect_suite()
+ unittest.TextTestRunner(verbosity=2).run(suite)
+
+def _run_with_nose():
+ # Call plugin_utils.init_all() so that all plug-ins are loaded
+ # (otherwise script tests, plug-in unit tests and plug-in integration
+ # tests would not work)
+ PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, 'plugins'))
+ assert os.path.isdir(PLUGIN_SOURCE_ROOT)
+ sys.path.append(PLUGIN_SOURCE_ROOT)
+ import plugin_utils
+ plugin_utils.init_all()
+
+ # Find all unittest_*.py files
+ test_files = []
+ def add_tests(path):
+ test_files.extend(_find_unittest_files(os.path.join(ROOT_PATH, path)))
+ add_tests('cone')
+ add_tests('scripts/tests')
+ add_tests('plugins')
+ add_tests('testautomation')
+
+
+ # Configure nose
+ import nose
+ plugins = nose.plugins.manager.DefaultPluginManager()
+ conf = nose.config.Config(plugins=plugins, testNames=test_files)
+
+ # Run the tests
+ args = ['--verbosity=3',
+ '--with-xunit',
+ '--xunit-file=cone-alltests.xml',
+ #'--collect-only',
+ ]
+ nose.run(config=conf, argv=[sys.argv[0]] + args)
+
+def main():
+ if '--with-nose' in sys.argv:
+ _run_with_nose()
+ else:
+ _run_without_nose()
+
+if __name__ == '__main__':
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/compare_api_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/compare_api_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,92 @@
+{% extends "cone_base.html" %}
+{% block title %}Compare API{% endblock %}
+{% block content %}
+ Configuration API compare
+ {% set columns = {'fqr':'Full reference',
+ 'name':'Name',
+ 'type':'Type',
+ 'desc':'Description',
+ } %}
+
+
+
+ {{ data.sourcedata.name }}
+
+ {{ data.targetdata.name }}
+
+
+ {%- for item in columns -%}
+ {{ columns[item] }}
+ {%- endfor -%}
+
+
+
+ {%- for item in columns -%}
+ {{ columns[item] }}
+ {%- endfor -%}
+
+ {%- for fqr in data.sourcedata.features -%}
+ {%- if fqr in data.targetdata.features and not data.sourcedata.features[fqr]._compare(data.targetdata.features[fqr], columns.keys()) -%}
+
+
+ {%- for colname in columns -%}
+ {%- if data.sourcedata.features[fqr][colname] != data.targetdata.features[fqr][colname] %}
+ "{{ data.sourcedata.features[fqr][colname] }}"
+ {%- else %}
+ {{ data.sourcedata.features[fqr][colname] }}
+ {%- endif -%}
+ {%- endfor -%}
+
+
+
+ {%- for colname in columns -%}
+ {%- if data.sourcedata.features[fqr][colname] != data.targetdata.features[fqr][colname] %}
+ "{{ data.targetdata.features[fqr][colname] }}"
+ {%- else %}
+ {{ data.targetdata.features[fqr][colname] }}
+ {%- endif -%}
+ {%- endfor -%}
+
+ {% endif -%}
+ {%- endfor -%}
+
+
+ {#- ----------------------------------------- -#}
+ {#- Report features that are only on one side -#}
+ {#- ----------------------------------------- -#}
+
+ {%- for fqr in data.sourcedata.features -%}
+ {%- if fqr not in data.targetdata.features -%}
+
+ {%- for colname in columns -%}
+ {{ data.sourcedata.features[fqr][colname] }}
+ {%- endfor -%}
+
+
+
+ {%- for colname in columns -%}
+
+ {%- endfor -%}
+
+ {% endif -%}
+ {%- endfor -%}
+
+ {%- for fqr in data.targetdata.features -%}
+ {%- if fqr not in data.sourcedata.features -%}
+
+ {%- for colname in columns -%}
+
+ {%- endfor -%}
+
+
+
+ {%- for colname in columns -%}
+ {{ data.targetdata.features[fqr][colname] }}
+ {%- endfor -%}
+
+ {% endif -%}
+ {%- endfor -%}
+
+
+
+{% endblock %}
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/compare_data_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/compare_data_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+{% extends "cone_base.html" %}
+{% block title %}Compare data{% endblock %}
+{% block content %}
+ Configuration data comparison
+
+
+
+ Source:
+ {{ data.sourcedata.name }}
+
+
+ Target:
+ {{ data.targetdata.name }}
+
+
+
+
+
+
+
+ Full reference
+ Name
+ Source value
+ Target value
+
+ {%- for fqr in data.sourcedata.features|sort -%}
+ {%- if fqr in data.targetdata.features and not data.sourcedata.features[fqr]._compare(data.targetdata.features[fqr], ['value']) -%}
+
+ {{ data.sourcedata.features[fqr]['fqr'] }}
+ {{ data.sourcedata.features[fqr]['name'] }}
+ {{ data.sourcedata.features[fqr]['value'] }}
+ {{ data.targetdata.features[fqr]['value'] }}
+
+ {% endif -%}
+ {%- endfor -%}
+
+
+{% endblock %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/cone_base.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/cone_base.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,121 @@
+
+
+
+{% block head %}
+
+{% block title %}{% endblock %} - ConE
+{% endblock head %}
+
+
+{% block content %}{% endblock %}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/cone_common.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/cone_common.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,283 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#!/usr/bin/env python
+##
+# @author Teemu Rytkonen
+
+import os
+import sys
+import logging
+import logging.config
+import re, fnmatch
+from optparse import Option
+import cone_tool
+
+
+"""
+try to import cone and modify the sys.paths if it does not succeed.
+This is done mainly for local installation and testing purposes.
+"""
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+try:
+ from cone.public import api, settings
+except ImportError:
+ sys.path.append(os.path.join(ROOT_PATH))
+ sys.path.append(os.path.join(ROOT_PATH,'..'))
+ from cone.public import api, settings
+
+# Common command line options used by all sub-actions
+COMMON_OPTIONS = [
+ Option("--print-settings",
+ dest="print_settings",
+ action="store_true",
+ help="Print all the default settings from the current setting container.",
+ default=False),
+
+ Option("--print-supported-impls",
+ action="store_true",
+ help="Print all supported ImplML XML namespaces and file extensions.",
+ default=False),
+
+ Option("--print-runtime-info",
+ action="store_true",
+ help="Print runtime information about ConE.",
+ default=False),
+
+ Option("-v", "--verbose",\
+ dest="verbose",\
+ help="""Print error, warning and information on system out.
+ Possible choices: Default is 3.
+ NONE (all) 0
+ CRITICAL 1
+ ERROR 2
+ WARNING 3
+ INFO 4
+ DEBUG 5""",
+ metavar="LEVEL",
+ default="3"),
+
+ Option("--log-file",
+ dest="log_file",
+ action="store",
+ type="string",
+ help="Location of the used log file. Default is 'cone.log'",
+ metavar="FILE",
+ default="cone.log"),
+
+ Option("--log-config",
+ dest="log_conf",
+ action="store",
+ type="string",
+ help="Location of the used logging configuration file. Default is 'logging.ini'",
+ metavar="FILE"),
+
+ Option("--username",
+ dest="username",
+ action="store",
+ type="string",
+ help="Username for webstorage operations. Not needed for filestorage or cpf storage. If the username \
+ is not given, the tool will use the loggged in username.",
+ metavar="USERNAME"),
+
+ Option("--password",
+ dest="password",
+ action="store",
+ type="string",
+ help="Password for webstorage operations. Not needed for filestorage or cpf storage. If the password \
+ is not given, the tool will prompt for password if needed.",
+ metavar="PASSWORD"),
+]
+
+def handle_common_options(options, settings=None):
+ """
+ Handle common command line options.
+ @param options: The parsed command line options.
+ @param settings: The settings to print if --print-settings is used.
+ Can be None, in which case the default settings are printed.
+ """
+ if options.log_conf:
+ open_log(options.verbose, options.log_file, options.log_conf)
+ else:
+ open_log(options.verbose, options.log_file)
+
+ exit = False
+
+ if options.print_settings:
+ if settings == None:
+ settings = get_settings([])
+ print_settings(settings)
+ exit = True
+
+ if options.print_supported_impls:
+ from cone.public import plugin
+ print "Supported ImplML namespaces:"
+ for ns in sorted(plugin.get_supported_namespaces()):
+ print ns
+
+ print ""
+ print "Supported ImplML file extensions:"
+ for ns in plugin.get_supported_file_extensions():
+ print ns
+ exit = True
+
+ if options.print_runtime_info:
+ print _get_runtime_info()
+ print "\nsys.path contents:"
+ print '\n'.join(sys.path)
+ exit = True
+
+ if exit: sys.exit()
+
+def _get_runtime_info():
+ if hasattr(sys, 'executable'): executable = sys.executable
+ else: executable = 'N/A'
+ info = ["ConE version: %s" % cone_tool.VERSION,
+ "Python version: %s" % sys.version,
+ "Platform: %s" % sys.platform,
+ "Executable: %s" % executable,
+ "Command line: %s" % ' '.join(sys.argv),
+ "Working dir: %s" % os.getcwd(),
+ "Script location: %s" % ROOT_PATH]
+ return '\n'.join(info)
+
+def open_log(verbose, log_file, log_conf_file=os.path.join(ROOT_PATH, 'logging.ini')):
+ try:
+ log_dir = os.path.dirname(log_file)
+ if log_dir != '' and not os.path.exists(log_dir):
+ os.makedirs(log_dir)
+
+ if (os.path.exists(log_conf_file)):
+ defaults = {'logfile': log_file, 'level': get_log_level_for_config(verbose)}
+ logging.config.fileConfig(log_conf_file, defaults)
+ else:
+ print "Failed to load logging configuration file: %s" % log_conf_file
+
+ logger = logging.getLogger('cone')
+ logger.info("Runtime info:\n%s" % _get_runtime_info())
+ logger.debug("sys.path contents:\n%s" % '\n'.join(sys.path))
+
+ def get_var(varname):
+ try: return os.environ[varname]
+ except KeyError: return 'N/A'
+ logger.debug("PATH: %s" % get_var('PATH'))
+ logger.debug("PYTHONPATH: %s" % get_var('PYTHONPATH'))
+ except IOError, e:
+ print "Cannot create log file. ", e
+
+def get_settings(files):
+ parser = settings.SettingsFactory.cone_parser()
+ parser.read(files)
+ return parser
+
+def print_settings(parser):
+ print_section(parser,"DEFAULT")
+ for section in parser.sections():
+ print_section(parser,section)
+
+def print_section(parser, section):
+ print "[%s]" % section
+ for (name,value) in parser.items(section):
+ print " %s = %s" % (name,value)
+
+
+def get_log_level(level):
+ """
+ Change the given user input log level to logging categorisation
+ """
+ # If the level is empty, revert to the default
+ if level in ('', None):
+ level = '3'
+
+ if level == '0' : return logging.NOTSET
+ elif level == '1' : return logging.CRITICAL
+ elif level == '2' : return logging.ERROR
+ elif level == '3' : return logging.WARNING
+ elif level == '4' : return logging.INFO
+ elif level == '5' : return logging.DEBUG
+ else : return logging.NOTSET
+
+def get_log_level_for_config(level):
+ """
+ Change the given user input to log level to logging configuration file
+ """
+
+ # If the level is empty, revert to the default
+ if level in ('', None):
+ level = 'WARNING'
+
+ if level == '0' : return 'NOTSET'
+ elif level == '1' : return 'CRITICAL'
+ elif level == '2' : return 'ERROR'
+ elif level == '3' : return 'WARNING'
+ elif level == '4' : return 'INFO'
+ elif level == '5' : return 'DEBUG'
+ else : return 'NOTSET'
+
+
+class ConfigurationNotFoundError(Exception):
+ """
+ Exception raised by get_config_list_from_project() if an invalid
+ configuration is given.
+ """
+ pass
+
+def get_config_list_from_project(project, configs, config_wildcards, config_regexes):
+ """
+ Return a list of configuration root names based on the given parameters.
+ @param project: The project from which to get the configuration list.
+ @param configs: List of configuration names to add. All of these should exist
+ in the project, or a ConfigurationNotFoundError is raised.
+ @param config_wildcards: List of wildcard patterns for including configurations.
+ @param config_regexs: List of regular expression patters for including configurations.
+ @return: A distinct list of configuration names matched by the given parameters. The
+ list contains matched configurations in the following order:
+ 1. Configurations specified in configs
+ 2. Configurations matched by wildcard patterns
+ 3. Configurations matched by regular expressions
+ If a configuration is matched by more than one of these, the first match determines
+ its placement in the list.
+ @raise ConfigurationNotFoundError: A configuration specified in configs is not
+ actually found in the project.
+ """
+ config_list = []
+
+ configs_in_project = sorted(project.list_configurations())
+
+ # Handle configurations specified with --configuration first
+ for config in configs:
+ if config not in configs_in_project:
+ raise ConfigurationNotFoundError("No such configuration: %s" % config)
+ if config not in config_list:
+ config_list.append(config)
+
+ # Then handle wildcards
+ if config_wildcards:
+ for config in configs_in_project:
+ for wildcard in config_wildcards:
+ if fnmatch.fnmatch(config, wildcard):
+ if config not in config_list:
+ config_list.append(config)
+
+ # Lastly handle regexes
+ if config_regexes:
+ for config in configs_in_project:
+ for pattern in config_regexes:
+ if re.match(pattern, config) is not None:
+ if config not in config_list:
+ config_list.append(config)
+
+ return config_list
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/cone_defaults.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/cone_defaults.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,51 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+
+[DEFAULT]
+# Settings for cone implmentation plugins
+# default path setting for all plugins
+# output path is a concatenation of output_root, output_subdir and plugin_output
+output_root=output
+output_subdir=
+plugin_output=
+output=%(output_root)s/%(output_subdir)s/%(plugin_output)s
+
+# plugin tags can be set as a dictionary
+plugin_tags = {}
+
+# plugin phase can be pre, normal or post
+plugin_phase = normal
+
+# Sections for different plugins
+[CRML]
+plugin_output = private/10202BE9
+plugin_tags = {'target' : ['rofs2','rofs3']}
+
+[GCFML]
+plugin_tags = {'target' : ['rofs2','rofs3']}
+
+[CONTENT]
+plugin_tags = {'target' : ['rofs3']}
+
+[MAKEML]
+plugin_tags = {'target' : ['makefile']}
+
+[RULEML]
+plugin_tags = {}
+
+[IMAGEML]
+plugin_tags = {'target' : ['rofs3']}
+
+[THEMEML]
+plugin_tags = {'target' : ['rofs3']}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/cone_subaction.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/cone_subaction.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+import fnmatch
+import re
+import logging
+
+
+def get_subactions(path,pattern):
+ """ Find out the cone subscripts that are present in the ROOT_PATH """
+ subacts = ActionContainer()
+ for file in os.listdir(path):
+ if fnmatch.fnmatch(file, pattern):
+ sact = SubAction(file,pattern)
+ subacts[sact.name] = sact
+ return subacts
+
+def get_log_level(level):
+ """
+ Change the given user input log level to logging categorisation
+ """
+ if level == 0 : return logging.NOTSET
+ elif level == 1 : return logging.CRITICAL
+ elif level == 2 : return logging.ERROR
+ elif level == 3 : return logging.WARNING
+ elif level == 4 : return logging.INFO
+ elif level == 5 : return logging.DEBUG
+ else : return logging.NOTSET
+
+class ActionContainer(object):
+ def __init__(self):
+ self._actions = {}
+
+ def __len__(self):
+ return len(self._actions)
+
+ def __getitem__(self, key):
+ return self._actions[key]
+
+ def __setitem__( self, key, value):
+ self._actions[key] = value
+
+ def __delitem__( self, key):
+ del self._actions[key]
+
+ def __iter__( self):
+ return self._actions.__iter__()
+
+class SubAction(object):
+ def __init__(self, scriptname, pattern):
+ self._scriptname = scriptname
+ self._pattern = pattern
+
+ @property
+ def name(self):
+ """ translate the pattern """
+ pattern = fnmatch.translate(self._pattern).replace('.*', '(.*)')
+ m = re.match(pattern, self._scriptname)
+ return m.group(1)
+
+ def run(self):
+ module = __import__(self._scriptname.replace('.py',''))
+ module.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/cone_tool.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/cone_tool.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys
+
+if sys.version_info[0] >= 3 or sys.version_info[0] <= 1:
+ print("WARNING: You are using not officially supported Python version:", sys.version_info[0], ".", sys.version_info[1], ".", sys.version_info[2])
+ print("Officially supported versions are 2.5 and 2.6")
+ sys.exit(1)
+elif sys.version_info[0] == 2:
+ if sys.version_info[1] == 5 or sys.version_info[1] == 6:
+ pass
+ elif sys.version_info[1] == 4 or sys.version_info[1] >= 7:
+ print("WARNING: You are using not officially supported Python version:", sys.version_info[0], ".", sys.version_info[1], ".", sys.version_info[2])
+ print("Officially supported versions are 2.5 and 2.6")
+ else:
+ print("WARNING: You are using not officially supported Python version:", sys.version_info[0], ".", sys.version_info[1], ".", sys.version_info[2])
+ print("Officially supported versions are 2.5 and 2.6")
+ sys.exit(1)
+
+import os
+import fnmatch
+import re
+import logging
+from optparse import OptionParser, OptionGroup
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+import cone
+import cone_subaction
+from cone.public import settings
+
+CONE_SCRIPT_PATTERN = 'conesub_*.py'
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SUBS = cone_subaction.get_subactions(ROOT_PATH, CONE_SCRIPT_PATTERN)
+ACTIONS = [sub for sub in SUBS]
+logger = logging.getLogger('cone')
+VERSION = cone.__version__
+if cone._svnrevision not in ("", "exported"):
+ VERSION += " (SVN %s)" % cone._svnrevision
+CONE_USAGE = "%prog [action] [options]."
+CONE_ACTIONS = '\n'
+for act in ACTIONS:
+ CONE_ACTIONS += ' %s\n' % act
+CONE_ACTION_HELP = "Available actions %s\nUse %%prog [action] -h to get action specific help." % CONE_ACTIONS
+
+def main():
+ parser = OptionParser(usage="%s\n\n%s" % (CONE_USAGE,CONE_ACTION_HELP),
+ version="%%prog %s" % VERSION,
+ prog="ConE")
+
+ # Set the path for cone .cfg files to the same directory as this script
+ settings.SettingsFactory.configpath = ROOT_PATH
+
+ try:
+ action = sys.argv[1]
+ subaction = SUBS[action]
+ print "Running action %s" % subaction.name
+ except (IndexError, KeyError):
+ (options, args) = parser.parse_args()
+ parser.error("Action must be given! See --help.")
+
+ subaction.run()
+
+
+if __name__ == "__main__":
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_compare.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_compare.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,288 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+import logging
+from optparse import OptionParser, OptionGroup
+import codecs
+
+import cone_common
+import time
+
+from cone.public import api, plugin, utils, exceptions
+from time import gmtime, strftime
+import report_util
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+VERSION = '1.0'
+
+log = logging.getLogger('cone')
+
+REPORT_SHORTCUTS = {
+ 'api': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'compare_api_report_template.html'),
+ 'api_comparison.html',
+ 'Report changes in feature definitions'),
+
+ 'data': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'compare_data_report_template.html'),
+ 'data_comparison.html',
+ 'Report changes in data values'),
+
+ 'crml_dc': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'crml_dc_report_template.html'),
+ 'crml_dc_report.html',
+ 'Report CRML data compatibility issues'),
+
+ 'crml_dc_csv': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'crml_dc_report_template.csv'),
+ 'crml_dc_report.csv',
+ 'Report CRML data compatibility issues (CSV format)'),
+}
+DEFAULT_SHORTCUT = 'data'
+
+def main():
+ shortcut_container = report_util.ReportShortcutContainer(REPORT_SHORTCUTS,
+ DEFAULT_SHORTCUT)
+
+ gset = cone_common.get_settings([os.path.join(ROOT_PATH,'conesub_compare.cfg')])
+
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ parser.add_option("-p", "--project",\
+ dest="project",\
+ help="defines the location of current project. Default is the current working directory.",\
+ default=".",\
+ metavar="STORAGE")
+
+ group = OptionGroup(parser, 'Compare options',
+ 'The generate function will create target files from a specific configuration.'\
+ 'The generate will always work with read-only mode of the project, so no changes are saved to project')
+
+ group.add_option("-s", "--sourceconfiguration",\
+ dest="sourceconfiguration",\
+ help="defines the name of the sourceconfiguration for the compare action. "\
+ "The configuration is expected to be located current storage.",\
+ metavar="CONFIG")
+
+ group.add_option("-t", "--targetconfiguration",\
+ dest="targetconfiguration",\
+ help="defines the name of the target configuration for the compare action. "\
+ "The configuration can be located in the current storage or it the configuration"\
+ "definition can contain a path to a storage. The storage definition is given as a path"\
+ "before semicolon. e.g. x:\data\configproject;productx.confml, test.cpf;root.confml",\
+ metavar="CONFIG")
+
+# group.add_option("--compare-dict",\
+# dest="compare_dict",\
+# action="store",
+# type="string",
+# help="Compare elements as a dictionary",
+# metavar="DICT",\
+# default=None)
+
+ group.add_option("--report",\
+ dest="report_file",\
+ action="store",
+ type="string",
+ help="The file where the comparison report is written."\
+ "By default this value is determined by the used "\
+ "report type. Example: --report report.html.",
+ metavar="FILE",\
+ default=None)
+
+ group.add_option("--template",\
+ dest="template",\
+ action="store",
+ type="string",
+ help="Template used in a report generation. By default "\
+ "this value is determined by the used report type. "\
+ "Example: --template report_template.html.",
+ metavar="FILE",\
+ default=None)
+
+ group.add_option("--report-type",
+ dest="report_type",
+ action="store",
+ type="string",
+ help="The type of the report to generate. This is a convenience "\
+ "switch for setting the used template. "\
+ "Possible values:\n "\
+ + shortcut_container.get_shortcut_help_text(),
+ metavar="TYPE",\
+ default=None)
+
+ group.add_option("--impl-filter",\
+ dest="impl_filter",\
+ action="store",
+ type="string",
+ help="The pattern used for filtering implementations for the "\
+ "comparison. See the switch --impl in action generate for "\
+ "more info. ",
+ metavar="PATTERN",\
+ default=None)
+
+ start_time = time.time()
+
+ parser.add_option_group(group)
+ (options, args) = parser.parse_args()
+
+ cone_common.handle_common_options(options, settings=gset)
+
+ if not options.sourceconfiguration: parser.error("sourceconfiguration must be given")
+ if not options.targetconfiguration: parser.error("targetconfiguration must be given")
+ if options.report_type and options.template:
+ parser.error("both --report-type and --template supplied; use only one of them")
+ if not shortcut_container.is_valid_shortcut(options.report_type):
+ parser.error("Invalid report type: %s" % options.report_type)
+
+ template_file, report_file = shortcut_container.determine_template_and_report(
+ options.report_type,
+ options.template,
+ options.report_file,
+ 'comparison')
+
+ action = CompareAction(options.project,
+ options.sourceconfiguration,
+ options.targetconfiguration,
+ template = template_file,
+ report_file = report_file,
+ impl_filter = options.impl_filter)
+ result = action.run_action()
+
+ resmap = {True: 0, False: 1}
+ sys.exit(resmap[result])
+
+
+
+class CompareAction(object):
+
+ def __init__(self, current, sourceconfig, targetconfig, **kwargs):
+ self.current = current
+ self.sourceconfig = sourceconfig
+ self.targetconfig = targetconfig
+ self.reportfile = kwargs.get("report_file", 'compare.html')
+ self.reporttemplate = kwargs.get('template', '')
+ self.columns = kwargs.get('columns', None)
+ self.impl_filter = kwargs.get('impl_filter',)
+
+ def run_action(self):
+ """
+ Run the action.
+ @return: True if successful, False if not.
+ """
+
+ currentprj = api.Project(api.Storage.open(self.current,"r"))
+ targetprj = None
+ (targetproject,targetconf) = self.parse_target_configuration(self.targetconfig)
+ print "Compare %s <> %s in %s" % (self.sourceconfig, targetconf, targetproject)
+ if targetproject != '':
+ targetprj = api.Project(api.Storage.open(targetproject,"r"))
+ else:
+ # The comparison doesn't seem to work if the same project
+ # object is used
+ #targetprj = currentprj
+ targetprj = api.Project(api.Storage.open(self.current,"r"))
+
+ source = currentprj.get_configuration(self.sourceconfig)
+ target = targetprj.get_configuration(targetconf)
+
+ print "Writing report to %s" % self.reportfile
+ sourcedata = {}
+ targetdata = {}
+ sourcedata['name'] = self.sourceconfig
+ targetdata['name'] = self.targetconfig
+ sourcedata['features'] = self.get_feature_api_data(source)
+ targetdata['features'] = self.get_feature_api_data(target)
+
+ impl_comp_data_proxy = ImplComparisonDataProxy(source,
+ target,
+ self.impl_filter)
+
+ template_data = {'sourcedata': sourcedata,
+ 'targetdata': targetdata,
+ 'impl_data': impl_comp_data_proxy}
+
+ result = report_util.generate_report(self.reporttemplate,
+ self.reportfile,
+ {'data': template_data})
+ print "Done."
+ return result
+
+ def parse_target_configuration(self,configpath):
+ """
+ return tuple (storage, configpath) from storagepath;root.confml.
+ returns ('', 'root.confml') from root.confml
+ """
+ elems = configpath.rsplit(';',2)
+ if len(elems) > 1:
+ return (elems[0],elems[1])
+ else:
+ return ('',elems[0])
+
+ def get_feature_api_data(self,config):
+ # Traverse through all features in the api
+ # and construct the data rows
+ data = {}
+ for elem in config.get_default_view().get_features('**'):
+ data[elem.fqr] = elem._obj
+ return data
+
+class ImplComparisonDataProxy(object):
+ """
+ Proxy object for loading implementation comparison data on demand.
+ """
+ def __init__(self, sourceconfig, targetconfig, impl_filter):
+ self.sourceconfig = sourceconfig
+ self.targetconfig = targetconfig
+ if impl_filter is None: self.impl_filter = '.*'
+ else: self.impl_filter = impl_filter
+
+ self._flat_data = None
+
+ @property
+ def flat(self):
+ try:
+ if self._flat_data is None:
+ self._flat_data = self._get_flat_comparison_data()
+ return self._flat_data
+ except Exception, e:
+ utils.log_exception(log, 'Error retrieving ImplComparisonDataProxy.flat!')
+ raise
+
+ def _get_flat_comparison_data(self):
+ log.debug("Loading implementations for comparison (impl filter = '%s')..." % (self.impl_filter))
+
+ try:
+ source_impls = plugin.get_impl_set(self.sourceconfig, self.impl_filter)
+ target_impls = plugin.get_impl_set(self.targetconfig, self.impl_filter)
+ except Exception, e:
+ utils.log_exception(log, 'Failed to load implementations!')
+ raise
+
+ log.debug("%d impl(s) in source." % len(source_impls))
+ log.debug("%d impl(s) in target." % len(target_impls))
+
+ log.debug("Generating flat comparison results...")
+ result = source_impls.flat_compare(target_impls)
+ log.debug("Generated %d result row(s)" % len(result))
+ return result
+
+if __name__ == "__main__":
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_export.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_export.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,259 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import fnmatch
+import logging
+from optparse import OptionParser, OptionGroup
+
+import cone_common
+from cone.public import api, plugin, utils, exceptions
+
+
+VERSION = '1.0'
+DEFAULT_EXT = '.cpf'
+
+logger = logging.getLogger('cone')
+DATA_NAME = 'confml/data.confml'
+
+def main():
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ parser.add_option("-c", "--configuration",
+ dest="configs",
+ action="append",
+ help="Defines the name of the configuration for the action, can be "\
+ "specified multiple times to include multiple configurations.",
+ metavar="CONFIG",
+ default=[])
+
+ parser.add_option("--config-wildcard",
+ action="append",
+ dest="config_wildcards",
+ help="Wildcard pattern for including configurations, e.g. "\
+ "product_langpack_*_root.confml",
+ metavar="WILDCARD",
+ default=[])
+
+ parser.add_option("--config-regex",
+ action="append",
+ dest="config_regexes",
+ help="Regular expression for including configurations, e.g. "\
+ "product_langpack_\\d{2}_root.confml",
+ metavar="REGEX",
+ default=[])
+
+ parser.add_option("-p", "--project",
+ dest="project",
+ help="defines the location of current project. Default is the "\
+ "current working directory.",\
+ default=".",
+ metavar="STORAGE")
+
+ group = OptionGroup(parser, 'Export options',
+ 'The export action is intended for exporting configurations '\
+ 'from one project (storage) to another. A project can be a '\
+ 'folder, a CPF or ZIP file, or a Carbon web storage URL. '\
+ # An ugly way to make newlines, someone should look into
+ # sub-classing optparse.HelpFormatter...
+ ' '\
+ 'Two different ways of exporting are supported: '\
+ ' '\
+ '1. Exporting multiple configurations into one new project using --remote '\
+ ' '\
+ '2. Exporting configurations into a number of new projects using --export-dir')
+
+ group.add_option("-r", "--remote",
+ dest="remote",
+ help="Defines the location of remote storage. All configurations included using "\
+ "--configuration, --config-wildcard and --config-regex are exported into "\
+ "the storage. If the remote storage location is not given, the default "\
+ "location is determined based on the first included source configuration name. "\
+ "E.g. 'example.confml' would be exported into 'example.cpf'",
+ metavar="STORAGE")
+
+ group.add_option("--export-dir",
+ help="Defines the directory where each included configuration is exported "\
+ "as a new project.",
+ default=None)
+
+ group.add_option("--export-format",
+ help="Defines the format into which projects are exported when using "\
+ "--export-dir. Possible values are 'cpf' (the default) and 'dir'.",
+ default=None)
+
+ group.add_option("-a","--add",
+ dest="added",
+ action="append",
+ type="string",
+ help="Adds a configuration layer to the given configuration as last element. "\
+ "The add operation can be used several times in a single command and it "\
+ "can create even an empty layer. "\
+ "Example --add foo/root.confml --add bar/root-confml.",
+ metavar="CONFIG",
+ default=None)
+
+ group.add_option("--exclude-folders",
+ dest="exclude_empty_folders",
+ action="store_true",
+ help="Excludes empty folders from export",
+ default=False)
+
+ parser.add_option_group(group)
+ (options, args) = parser.parse_args()
+
+ cone_common.handle_common_options(options)
+
+ # Check options
+ if options.export_format and options.export_dir is None:
+ parser.error("--export-format can only be used in conjunction with --export-dir")
+ if options.export_dir and options.remote:
+ parser.error("--export-dir and --remote cannot be used at the same time")
+ if options.export_format and options.export_format.lower() not in ('dir', 'cpf'):
+ parser.error("Invalid export format '%s'" % options.export_format)
+ if options.export_dir and not (options.configs or options.config_wildcards or options.config_regexes):
+ parser.error("Use of --export-dir requires at least one configuration to be specified")
+ if options.export_dir and os.path.isfile(options.export_dir):
+ parser.error("Given export directory '%s' is a file")
+
+ # Open the project and find out the active configuration
+ project = api.Project(api.Storage.open(options.project, "r"))
+ try:
+ active_root = project.get_storage().get_active_configuration()
+ except AttributeError:
+ active_root = None
+
+ # Collect the list of configurations specified from the command line
+ config_list = []
+ if options.configs or options.config_wildcards or options.config_regexes:
+ try:
+ config_list = cone_common.get_config_list_from_project(
+ project = project,
+ configs = options.configs,
+ config_wildcards = options.config_wildcards,
+ config_regexes = options.config_regexes)
+ except cone_common.ConfigurationNotFoundError, e:
+ parser.error(str(e))
+
+ # Use the active configuration if no configurations are specifically given
+ if len(config_list) == 0:
+ if active_root is None:
+ parser.error("No configurations given and the project does not have an active root")
+ else:
+ logger.info('No configurations given! Using active root configuration %s' % active_root)
+ config_list = [active_root]
+
+ # Perform the export
+ if options.export_dir:
+ _export_to_dir(project = project,
+ export_dir = options.export_dir,
+ export_format = options.export_format or 'cpf',
+ configs = config_list,
+ added_layers = options.added,
+ empty_folders = not options.exclude_empty_folders)
+ else:
+ _export_to_storage(project = project,
+ remote_project_location = options.remote,
+ configs = config_list,
+ added_layers = options.added,
+ empty_folders = not options.exclude_empty_folders)
+
+
+def _export_to_storage(project, remote_project_location, configs, added_layers, empty_folders):
+ assert len(configs) > 0
+
+ # If the remote storage is not given, determine it automatically based
+ # on the first specified configuration name
+ if not remote_project_location:
+ remotename, ext = os.path.splitext(os.path.basename(configs[0]))
+ remotename += DEFAULT_EXT
+ logger.info('No remote storage given! Using source configuration name %s' % remotename)
+ remote_project_location = remotename
+
+ remote_project = api.Project(api.Storage.open(remote_project_location, "w"))
+ for config_path in configs:
+ config = project.get_configuration(config_path)
+ project.export_configuration(config,
+ remote_project.storage,
+ empty_folders = empty_folders)
+ print "Export %s to %s done!" % (config_path, remote_project_location)
+
+ # Setting first as active configuration if there are more than one configuration defined.
+ configs = remote_project.list_configurations()
+ if len(configs):
+ try:
+ remote_project.get_storage().set_active_configuration(configs[0])
+ except AttributeError:
+ pass
+
+ remote_project.save()
+ remote_project.close()
+
+ _add_layers(project, remote_project_location, added_layers, empty_folders)
+
+def _add_layers(source_project, remote_project_location, added_configs, empty_folders):
+ """
+ Add new configuration layers from source_project into
+ """
+ if not added_configs:
+ return
+
+ target_project = api.Project(api.Storage.open(remote_project_location, "a"))
+ for target_config_name in target_project.list_configurations():
+ target_config = target_project.get_configuration(target_config_name)
+
+ for added_config_name in added_configs:
+ # Add layers only once
+ if not target_project.storage.is_resource(added_config_name):
+ logger.info('Adding configuration %s' % added_config_name)
+
+ if source_project.storage.is_resource(added_config_name):
+ # The configuration exists in the source project, export it from there
+ existing_config = source_project.get_configuration(added_config_name)
+ source_project.export_configuration(existing_config,
+ target_project.storage,
+ empty_folders = empty_folders)
+ else:
+ # The given configuration does not exist in the source project,
+ # create a new empty layer
+ logger.info("Creating new layer %s." % added_config_name)
+ new_config = target_project.create_configuration(added_config_name)
+ new_config.create_configuration(DATA_NAME)
+
+ # Include the added configuration in the configuration root
+ target_config.include_configuration(utils.resourceref.norm(added_config_name))
+
+ target_project.save()
+ target_project.close()
+
+def _export_to_dir(project, export_dir, export_format, configs, added_layers, empty_folders):
+ if not os.path.exists(export_dir):
+ os.makedirs(export_dir)
+
+ for config in configs:
+ remote_name, _ = os.path.splitext(os.path.basename(config))
+ if export_format.lower() == 'cpf':
+ remote_name += '.cpf'
+ elif export_format.lower() == 'dir':
+ remote_name += '/'
+
+ remote_name = os.path.join(export_dir, remote_name)
+ _export_to_storage(project, remote_name, [config], added_layers, empty_folders)
+
+if __name__ == "__main__":
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_generate.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_generate.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,32 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+
+# conesub_generate action specific configuration. The configuration option names
+# are the same what are documented in the command line help.
+
+[DEFAULT]
+verbose = 3
+# layers as a plural, which can be a comma separated list of layer ids.
+layers = -1
+# implementation path filter
+impls =
+impl-tags =
+sets =
+adds =
+report =
+template =
+
+# extra settings to configure generation
+# read cfg files
+cfgsettings = imaker_variantdir.cfg
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_generate.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_generate.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,418 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+import logging
+from optparse import OptionParser, OptionGroup
+import cone_common
+import time
+from os import path
+from cone.public import api, plugin, utils, exceptions
+import generation_report
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+VERSION = '1.0'
+
+
+def main():
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ parser.add_option("-c", "--configuration",\
+ dest="configuration",\
+ help="defines the name of the configuration for the action",\
+ metavar="CONFIG")
+
+ parser.add_option("-p", "--project",\
+ dest="project",\
+ help="defines the location of current project. Default is the current working directory.",\
+ default=".",\
+ metavar="STORAGE")
+
+ gen_group = OptionGroup(parser, 'Generate options',
+ 'The generate function will create target files from a specific configuration.'\
+ 'The generate will always work with read-only mode of the project, so no changes are saved to project')
+
+ gen_group.add_option("-o", "--output",\
+ dest="output",\
+ help="defines the target folder where the files are is generated or copied",\
+ metavar="FOLDER",\
+ default="output")
+
+ gen_group.add_option("-l", "--layer",\
+ dest="layers",\
+ type="int",
+ action="append",
+ help="define layers of the configuration that are included to the output. "\
+ "The layer operation can be used several times in a single command."\
+ "Example -l -1 --layer=-2, which would append a layers -1 and -2 to the layers => layers = -1,-2",
+ metavar="LAYER",\
+ default=None)
+
+ gen_group.add_option("--all-layers",
+ dest="all_layers",
+ action="store_true",
+ help="Include all layers in generation. This switch overrides all other layer "\
+ "configurations (iMaker API and using the --layer parameter)",
+ default=False)
+
+ gen_group.add_option("-i", "--impl",\
+ dest="impls",\
+ action="append",
+ help=\
+"""Define a Python regular expression filter for actual ImplML plugin(s) that needs to be executed. The whole path to ImplML filename is used in the regexp matching.
+The impl operation can be used several times in a single command.
+
+Example1 --impl crml => matches for any ImplML file that has a CrML string in the path.
+Example2 --impl makeml$ => matches for ImplML file that has ends with MakeML string.
+""",
+ metavar="IMPLS",\
+ default=None)
+
+ gen_group.add_option("--impl-tag",\
+ dest="tags",\
+ type="string",
+ action="append",
+ help="define a tag for the implementations that are included to the output. "\
+ "A tag is name value pair and has the following format: name:value, e.g. target:rofs3."\
+ "Example --impl-tag=target:uda --impl-tag=target:content, which would include impls include both tags.",
+ metavar="TAG",\
+ default=None)
+
+ gen_group.add_option("--impl-tag-policy",\
+ dest="tags_policy",\
+ type="string",
+ action="append",
+ help="Policy for implementation tags. May have one of the following values: --impl-tag-policy=AND, --impl-tag-policy=OR. "\
+ "Default is OR.",
+ metavar="TAGS_POLICY",\
+ default=None)
+
+ gen_group.add_option("-s", "--set",\
+ dest="overrides",\
+ action="append",
+ type="string",
+ help="Override a ConfML reference in the execution."\
+ "The set operation can be used several times in a single command."\
+ "Example -s foo.bar=10 -s foo.fea='test'.",
+ metavar="SET",\
+ default=None)
+
+ gen_group.add_option("--add",\
+ dest="added",\
+ action="append",
+ type="string",
+ help="Add a given configuration to the given configuration as last element."\
+ "The add operation can be used several times in a single command."\
+ "Example --add foo/root.confml --add bar/root-confml.",
+ metavar="CONF",\
+ default=None)
+
+ gen_group.add_option("-r", "--report",\
+ dest="report",\
+ action="store",
+ type="string",
+ help="Generates a report about settings that are properly generated."\
+ "Example -r report.html.",
+ metavar="FILE",\
+ default=None)
+
+ gen_group.add_option("-t", "--template",\
+ dest="template",\
+ action="store",
+ type="string",
+ help="Template used in report generation."\
+ "Example -t report_template.html.",
+ metavar="FILE",\
+ default=None)
+
+ gen_group.add_option("--report-data-output",\
+ type="string",
+ help="Specifies a file where intermediary report data is generated.",
+ metavar="FILE",\
+ default=None)
+
+ gen_group.add_option("-n", "--dryrun",\
+ dest="dryrun",\
+ action="store_true",
+ help="Executes generation without generation output.",
+ default=False)
+
+ gen_group.add_option("--add-setting-file",\
+ dest="settings",\
+ action="append",
+ type="string",
+ help="Generate specific settings in ini format."\
+ "Example -o my_generate_settings.cfg.",
+ metavar="FILE",\
+ default=None)
+
+ layers = None
+ current = None
+ remote = None
+
+ start_time = time.time()
+
+ parser.add_option_group(gen_group)
+ (options, args) = parser.parse_args()
+
+ settinglist = [os.path.join(ROOT_PATH,'conesub_generate.cfg')]
+ if options.settings:
+ for setting_file in options.settings:
+ settinglist.append(os.path.normpath(os.path.join(ROOT_PATH, setting_file)))
+ gset = cone_common.get_settings(settinglist)
+
+ cone_common.handle_common_options(options, settings=gset)
+
+ current = api.Project(api.Storage.open(options.project,"r"))
+ active_root = current.get_storage().get_active_configuration()
+ if not options.configuration:
+ if active_root == "":
+ parser.error("configuration must be given")
+ else:
+ logging.getLogger('cone').info('No configuration given! Using active root configuration %s' % active_root)
+ options.configuration = active_root
+ try:
+ config = current.get_configuration(options.configuration)
+ except exceptions.NotFound:
+ parser.error("No such configuration: %s" % options.configuration)
+ reffilters = None
+ implfilters = None
+ impltags = None
+
+ # Include possible additional configurations
+ if options.added:
+ for configname in options.added:
+ logging.getLogger('cone').info('Adding configuration %s' % configname)
+ config.include_configuration(utils.resourceref.norm(configname))
+
+ # Get defs from configuration
+ try:
+ layer_str_list = (config.get_default_view().get_feature('imakerapi.cone_layers').get_value() or '').split(',')
+ # Make sure that empty layers definitions are ignored
+ layer_str_list = utils.distinct_array(layer_str_list)
+ if '' in layer_str_list:
+ layer_str_list.remove('')
+ # converting layrs identifiers from strings to int
+ layerdefs = []
+ for layerstr in layer_str_list:
+ try:
+ layerdefs.append(int(layerstr))
+ except ValueError, e:
+ logging.getLogger('cone').error('Invalid layer filter %s' % layerstr)
+ implfilters = (config.get_default_view().get_feature('imakerapi.cone_impls').get_value() or '').split(',')
+ except exceptions.NotFound:
+ layerdefs = []
+ implfilters = []
+ pass
+
+ # Get filters from command line if they exist => cmd overrides configuration
+ if options.layers:
+ layerdefs = options.layers
+ if options.impls:
+ implfilters = options.impls
+ if options.tags and len(options.tags) > 0:
+ impltags = {}
+ for tag in options.tags:
+ (name,value) = tag.split(':',2)
+ existingvalue = impltags.get(name,[])
+ existingvalue.append(value)
+ impltags[name] = existingvalue
+ logging.getLogger('cone').info('Tag filter %s' % impltags)
+ else:
+ impltags = None
+
+ tags_policy = 'OR'
+ if options.tags_policy:
+ tags_policy = options.tags_policy[0]
+
+ # Finally, --all-layers overrides all other layer settings
+ if options.all_layers:
+ layerdefs = []
+
+ logging.getLogger('cone').info('Layer filter %s' % layerdefs)
+
+ # Add reffilters only if the given layerids are somehow reasonable
+ if len(layerdefs) > 0:
+ # get the data references from given layers
+ logging.getLogger('cone').info('Getting layer specific data reference from %s' % layerdefs)
+ reffilters = []
+ for layerid in utils.distinct_array(layerdefs):
+ logging.getLogger('cone').info('Searching layer %s' % layerid)
+ layer = config.get_configuration_by_index(layerid)
+ refs = _get_new_refs(reffilters, layer.list_leaf_datas())
+ logging.getLogger('cone').info("Refs from layer '%s'\n%s" % (layer.get_path(), '\n'.join(refs)))
+ reffilters += refs
+
+
+ if options.overrides:
+ config.add_configuration(api.Configuration('tempdata.confml'))
+ for override in options.overrides:
+ (ref,value) = override.split('=',1)
+ config.get_default_view().get_feature(ref).set_value(value)
+
+ # Make sure that the output folder exists
+ if not os.path.exists(options.output):
+ os.makedirs(options.output)
+
+ impls = plugin.filtered_impl_set(config,implfilters)
+ impls.output = options.output
+
+ logging.getLogger('cone').info("Supported implementation file extensions: %r" % plugin.get_supported_file_extensions())
+
+# logging.getLogger('cone').debug('Loaded implementations:')
+# for impl in impls:
+# msg = "File '%s', impl. type '%s', class '%s', phase '%s'" % \
+# (impl.ref, impl.IMPL_TYPE_ID, type(impl).__name__, impl.invocation_phase())
+# logging.getLogger('cone').debug(msg)
+
+
+ # Create temporary variables
+ temp_feature_refs = impls.create_temp_features(config)
+ if reffilters is not None:
+ reffilters.extend(temp_feature_refs)
+ logging.getLogger('cone').info('Refs from temporary variables:\n%s' % '\n'.join(temp_feature_refs))
+
+
+
+ # ---------------
+ # Generate output
+ # ---------------
+
+ rule_exec_results = []
+
+ # Create an implementation container with all the relevant implementations
+ all_impls = impls.filter_implementations(tags=impltags, policy=tags_policy)
+
+ # Implementations taking part in output generation
+ gen_impls = plugin.ImplSet()
+ context = plugin.GenerationContext()
+ context.configuration = config
+ log = logging.getLogger('cone')
+ for phase in plugin.ImplSet.INVOCATION_PHASES:
+ phase_impls = all_impls.filter_implementations(phase=phase)
+ log.info("Generating phase '%s', %d implementation(s)" % (phase, len(phase_impls)))
+
+ context.phase = phase
+ # No use going any further if there are no implementations
+ # for the phase at all
+ if len(phase_impls) == 0:
+ continue
+
+ # Load and execute rules for this phase
+ # -------------------------------------
+# relation_container = phase_impls.get_relation_container()
+# log.info("%d rule(s) for phase '%s'" % (relation_container.get_relation_count(), phase))
+# if relation_container.get_relation_count() > 0:
+# log.info("Executing rules...")
+# results = relation_container.execute()
+# log.info("Got %d execution result(s)" % len(results))
+# rule_exec_results.extend(results)
+
+
+ # Create an implementation container for the phase with
+ # the new reffilters and generate output with it
+ # -----------------------------------------------------
+ impls = phase_impls.filter_implementations(refs=reffilters)
+ log.info("%d implementation(s) after filtering for phase '%s'" % (len(impls), phase))
+ if len(impls) > 0:
+ if impltags != None:
+ context.tags = impltags
+ context.tags_policy = tags_policy
+ impls.output = options.output
+ log.info("Generating output...")
+ impls.generate(context)
+ impls.post_generate(context)
+
+ # Add new refs after generation
+# if reffilters != None and len(reffilters) > 0:
+# layer = config.get_configuration_by_index(-1)
+# new_refs = _get_new_refs(reffilters, layer.list_leaf_datas())
+# log.info('Added %d ref(s) after generation:\n%s' % (len(new_refs), '\n'.join(new_refs)))
+# reffilters += new_refs
+
+ # Add new references after each phase execution
+ # ---------------------------------------
+ if reffilters != None and len(reffilters) > 0:
+ layer = config.get_configuration_by_index(-1)
+ new_refs = _get_new_refs(reffilters, layer.list_leaf_datas())
+ log.info('Added %d ref(s) after phase %s execution:\n%s' % (len(new_refs), phase, '\n'.join(new_refs)))
+ reffilters += new_refs
+
+ # Add the implementations to the set of implementations participating
+ # in output generation (used in the report)
+ for impl in impls:
+ for actual_impl in impl.get_all_implementations():
+ logging.getLogger('cone').info('Adding impl %s' % impl)
+ gen_impls.add(actual_impl)
+
+ rule_exec_results = context.results
+ print "Generated %s to %s!" % (options.configuration, impls.output)
+
+
+ # ---------------
+ # Generate report
+ # ---------------
+
+ # If reporting is enabled collect data for report
+ if options.report != None or options.report_data_output != None:
+ logging.getLogger('cone').info('Collecting data for report.')
+ all_refs = reffilters or utils.distinct_array(config.get_configuration_by_index(-1).list_leaf_datas())
+ logging.getLogger('cone').info('Collecting data found refs %s' % all_refs)
+ logging.getLogger('cone').info('Collecting data found gen_impls %s' % gen_impls)
+ rep_data = generation_report.collect_report_data(config, options, all_refs, gen_impls, rule_exec_results)
+ logging.getLogger('cone').info('Collecting data found rep_data %s' % rep_data)
+
+ duration = str("%.3f" % (time.time() - start_time) )
+ rep_data.set_duration( duration )
+
+ # Save intermediary report data file if necessary
+ if options.report_data_output != None:
+ logging.getLogger('cone').info('Dumping report data to %s' % options.report_data_output)
+ print "Dumping report data to '%s'" % options.report_data_output
+ generation_report.save_report_data(rep_data, options.report_data_output)
+
+ # Generate the report if necessary
+ if options.report != None:
+ generation_report.generate_report(rep_data, options.report, options.template)
+ print_summary(rep_data)
+
+ if current: current.close()
+
+def _get_new_refs(old_refs, new_refs):
+ """
+ Return a distinct array of refs in ``new_refs`` that are not present in ``old_refs``.
+ """
+ result = []
+ for ref in new_refs:
+ if ref not in old_refs and ref not in result:
+ result.append(ref)
+ return result
+
+def print_summary(rep_data):
+ """ Prints generation summary to logger and console. """
+ print "\nGENERATION SUMMARY:"
+ print "--------------------"
+ print "Refs in files: %s" % rep_data.nbr_of_refs
+ print "Refs with no implementation: %s" % rep_data.nbr_of_refs_noimpl
+ print "Generation duration: %s" % rep_data.duration
+ print "\n\n"
+
+
+if __name__ == "__main__":
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_import_browserbookmarks.py.old
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_import_browserbookmarks.py.old Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+
+import os
+import logging
+import codecs
+
+from optparse import OptionParser, OptionGroup
+
+import cone_common
+from cone.public import api, plugin, utils, exceptions, container
+
+VERSION = '1.0'
+
+logger = logging.getLogger('cone')
+elems = {
+'Type': 0,
+'Name': 1,
+'ParentFolderName': 2,
+'URL': 3,
+'AccessPoint': 4,
+'UserName': 5,
+'Password': 6,
+'ReadOnly': 7,
+'FactoryItem': 8,
+'ContextId': 9,
+'Preferred': 10
+ }
+
+def main():
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_option("-c", "--configuration",\
+ dest="configuration",\
+ help="defines the name of the configuration for the action",\
+ metavar="CONFIG")
+
+ parser.add_option("-v", "--verbose",\
+ dest="verbose",\
+ help="Print error,warning and information on system out. \
+ Possible choises: Default is 3.\
+ NONE 0.\
+ CRITICAL 1\
+ ERROR 2\
+ WARNING 3\
+ INFO 4\
+ DEBUG 5\
+ ",\
+ default=3,\
+ metavar="LEVEL")
+ parser.add_option("-p", "--project",\
+ dest="project",\
+ help="defines the location of current project. Default is the current working directory.",\
+ default=".",\
+ metavar="STORAGE")
+
+ bgroup = OptionGroup(parser, 'Import browser bookmarks options',
+ 'The import_browserbookmarks functionality is meant to import browser bookmarks to a given configuration.')
+
+ bgroup.add_option("-i", "--input",\
+ dest="input",\
+ type="string",
+ help="input BrowserBookmarks file for the importing.",
+ metavar="FILE",\
+ default=None)
+
+ layers = None
+ current = None
+
+ parser.add_option_group(bgroup)
+ (options, args) = parser.parse_args()
+
+ api.get_console_logger().setLevel(cone_common.get_log_level(options.verbose))
+
+ if not options.input:
+ parser.error("Input file must be given!")
+
+ logger.info('Open file %s.' % options.input)
+
+
+ current = api.Project(api.Storage.open(options.project,"a"))
+ active_root = current.get_storage().get_active_configuration()
+ if not options.configuration:
+ if active_root == "":
+ parser.error("configuration must be given")
+ else:
+ logging.getLogger('cone').info('No configuration given! Using active root configuration %s' % active_root)
+ options.configuration = active_root
+ config = current.get_configuration(options.configuration)
+ dview = config.get_default_view()
+ bookmarkfea = dview.get_feature('BookmarkItems.BookmarkItem')
+
+ inputfile = codecs.open(options.input,encoding="utf16")
+ firstelem = True
+ for line in inputfile.readlines():
+ # skip comments
+ data = line.split('#',1)
+ dataelem = data[0]
+ dataelem = dataelem.strip()
+ dataelem = dataelem.rstrip('\n')
+
+ if dataelem != "":
+ # Split the datarow in to data elems
+ #print "DATAELEM: %s!" % dataelem
+ dataelems = dataelem.split(',')
+ print "Elem found %s" % str(dataelems[elems['Name']])
+ # Build the new data sequence
+ browserseq = []
+ for feaname in bookmarkfea.list_features():
+ try:
+ browserseq.append(str(dataelems[elems[feaname]]))
+ except IndexError:
+ pass
+
+ print browserseq
+ if firstelem:
+ bookmarkfea.add_sequence(browserseq, policy=container.REPLACE)
+ data = bookmarkfea.get_data()[-1]
+ data._get_data().policy = 'replace'
+ firstelem = False
+ else:
+ bookmarkfea.add_sequence(browserseq, policy=container.APPEND)
+
+ config.save()
+
+ logger.info('Done!')
+
+if __name__ == "__main__":
+ main()
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_info.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_info.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,672 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, zipfile, os
+import re, fnmatch
+import logging
+
+from optparse import OptionParser, OptionGroup
+
+import cone_common
+from cone.public import api, plugin, utils, exceptions
+from cone.confml import persistentconfml
+from cone.storage.filestorage import FileStorage
+import report_util
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+
+VERSION = '1.0'
+
+
+REPORT_SHORTCUTS = {
+ 'api': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'info_api_report_template.html'),
+ 'api_report.html',
+ "Create a report of the configuration's ConfML API."),
+
+ 'value': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'info_value_report_template.html'),
+ 'value_report.html',
+ "Create a report of the configuration's data values. Multiple "\
+ "configurations can also be given using --configurations"),
+
+ 'value_csv': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'info_value_report_template.csv'),
+ 'value_report.csv',
+ "Create a report of the configuration's data values (CSV format)."),
+
+ 'api_csv': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'info_api_report_template.csv'),
+ 'api_report.csv',
+ "Create a report of the configuration's ConfML API (CSV format)."),
+
+ 'impl': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'info_impl_report_template.html'),
+ 'impl_report.html',
+ 'Create a report of all implementations in the configuration.'),
+
+ 'content': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'info_content_report_template.html'),
+ 'content_report.html',
+ 'Create a report of the content files in the configuration.'),
+}
+
+def main():
+ shortcut_container = report_util.ReportShortcutContainer(REPORT_SHORTCUTS,
+ None)
+
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ parser.add_option("-c", "--configuration",
+ action="append",
+ dest="configs",
+ help="Defines a configuration to use in report generation or info printout. "\
+ "May be defined more than once, but multiple configuration will only "\
+ "do anything if the report type supports them. If multiple configurations "\
+ "are not supported, the first one will be used",
+ metavar="CONFIG",
+ default=[])
+
+ parser.add_option("--config-wildcard",\
+ action="append",
+ dest="config_wildcards",
+ help="Wildcard pattern for including configurations, e.g. product_langpack_*_root.confml",
+ metavar="WILDCARD",
+ default=[])
+
+ parser.add_option("--config-regex",\
+ action="append",
+ dest="config_regexes",
+ help="Regular expression for including configurations, e.g. product_langpack_\\d{2}_root.confml",
+ metavar="REGEX",
+ default=[])
+
+ parser.add_option("-p", "--project",\
+ dest="project",\
+ help="defines the location of current project. Default is the current working directory.",\
+ default=".",\
+ metavar="STORAGE")
+
+ info_group = OptionGroup(parser, 'Info options',
+ 'The info functionality is meant for printing information about the '\
+ 'contents of a cpf/zip file or Configuration Project (folder). Two '\
+ 'separate use cases are currently supported: '\
+ '1. Printing basic information about a project or configuration to '\
+ ' stdout. '\
+ '2. Creating a report of the contents of a configuration or configurations.')
+
+ info_group.add_option("--report-type",
+ help="The type of the report to generate. This is a convenience "\
+ "switch for setting the used template. "\
+ "Possible values: "\
+ + shortcut_container.get_shortcut_help_text(),
+ metavar="TYPE",\
+ default=None)
+
+ info_group.add_option("--report",
+ help="The file where the configuration info report is written."\
+ "By default this value is determined by the used "\
+ "report type. Example: --report report.html.",
+ metavar="FILE",\
+ default=None)
+
+ info_group.add_option("--template",
+ help="Template used in a report generation. By default "\
+ "this value is determined by the used report type. "\
+ "Example: --template report_template.html.",
+ metavar="FILE",\
+ default=None)
+
+ info_group.add_option("--impl-filter",
+ help="The pattern used for filtering implementations for the "\
+ "report. See the switch --impl in action generate for "\
+ "more info. ",
+ metavar="PATTERN",
+ default='.*')
+
+ info_group.add_option("--view-file",
+ help="External ConfML file containing the view used for filtering "\
+ "the features listed in the setting value report. The first view "\
+ "defined in the file will be used.",
+ metavar="FILE",
+ default=None)
+
+ parser.add_option_group(info_group)
+
+ (options, args) = parser.parse_args()
+ cone_common.handle_common_options(options)
+
+ if not shortcut_container.is_valid_shortcut(options.report_type):
+ parser.error("Invalid report type: %s" % options.report_type)
+ if (options.report_type or options.template) and \
+ (not options.configs and not options.config_wildcards and not options.config_regexes):
+ parser.error("Report type or template specified but configuration(s) not given!")
+ if options.view_file and not os.path.isfile(options.view_file):
+ parser.error("No such file: %s" % options.view_file)
+
+ # Load view from the specified file if necessary
+ view = None
+ if options.view_file:
+ try:
+ view = _load_view_from_file(options.view_file)
+ print "Loaded view '%s' from '%s'" % (view.get_name(), options.view_file)
+ except ViewLoadError, e:
+ print e
+ sys.exit(1)
+
+ current = api.Project(api.Storage.open(options.project,"r"))
+ print "Opened project in %s" % options.project
+
+ # Get a list of configurations if necessary
+ config_list = None
+ if options.configs or options.config_wildcards or options.config_regexes:
+ try:
+ config_list = cone_common.get_config_list_from_project(
+ project = current,
+ configs = options.configs,
+ config_wildcards = options.config_wildcards,
+ config_regexes = options.config_regexes)
+ except cone_common.ConfigurationNotFoundError, e:
+ parser.error(str(e))
+
+ # Specifying configurations using --configuration should always either result
+ # in an error or a configuration, so if there are no configurations, it
+ # means that the user specified only wildcards and/or patterns, and none
+ # matched
+ if len(config_list) == 0:
+ parser.error("No matching configurations for wildcard(s) and/or pattern(s).")
+
+
+ if config_list is not None:
+ # One or more configurations have been specified
+
+ if options.report_type is not None or options.template is not None:
+ # Generating a report
+
+ # Create a list of configurations
+ configs = []
+ for config_name in config_list:
+ configs.append(current.get_configuration(config_name))
+
+ # Generate the report
+ if options.report_type: report_name = options.report_type + '_info'
+ else: report_name = 'info'
+ template, report = shortcut_container.determine_template_and_report(
+ options.report_type,
+ options.template,
+ options.report,
+ report_name)
+ data_providers = {'impl_data' : ImplDataProvider(configs[0], options.impl_filter),
+ 'api_data' : ApiDataProvider(configs[0]),
+ 'content_data': ContentDataProvider(configs[0]),
+ 'value_data' : ValueDataProvider(configs, view)}
+ report_util.generate_report(template, report, {'data': ReportDataProxy(data_providers)})
+ else:
+ # Printing configuration info
+ config_name = config_list[0]
+ config = current.get_configuration(config_name)
+ print "Opened configuration %s" % config_name
+ print "Features %s" % len(config.get_default_view().list_all_features())
+ print "Impl files %s" % len(plugin.get_impl_set(config).list_implementation())
+
+ else:
+ print "Configurations in the project."
+ configlist = current.list_configurations()
+ configlist.sort()
+ for config in configlist:
+ print config
+ if current: current.close()
+
+
+# ============================================================================
+# Report data proxy and data providers
+# ============================================================================
+
+class ReportDataProxy(object):
+ """
+ Proxy object for loading report data on demand.
+
+ It is used so that e.g. when generating an API report, the
+ implementations are not unnecessarily loaded. The class utilizes
+ ReportDataProviderBase objects to handle the actual data generation,
+ and logs any exceptions that happen there.
+ """
+ def __init__(self, data_providers):
+ assert isinstance(data_providers, dict), "data_providers must be a dict!"
+ self._data_providers = data_providers
+
+ def __getattr__(self, attrname):
+ if attrname in self._data_providers:
+ try:
+ return self._data_providers[attrname].get_data()
+ except Exception, e:
+ utils.log_exception(logging.getLogger('cone'),
+ "Exception getting %s: %s" % (attrname, e))
+ else:
+ return super(ReportDataProxy, self).__getattr__(attrname)
+
+class ReportDataProviderBase(object):
+ """
+ Report data provider base class for lazy-loading of report data.
+ """
+ def get_data(self):
+ """
+ Return the report data.
+
+ The data is generated on the first call to this, and later the
+ cached data is returned.
+ """
+ CACHE_ATTRNAME = "__datacache"
+ if hasattr(self, CACHE_ATTRNAME):
+ return getattr(self, CACHE_ATTRNAME)
+ else:
+ data = self.generate_data()
+ setattr(self, CACHE_ATTRNAME, data)
+ return data
+
+ def generate_data(self):
+ """
+ Generate the actual report data. Called when get_data() is called
+ the first time.
+ """
+ raise NotImplmentedError()
+
+# ----------------------------------------------------------------------------
+
+class ApiDataProvider(ReportDataProviderBase):
+ def __init__(self, config):
+ self._config = config
+
+ def generate_data(self):
+ columns = {'fqr':'Full reference',
+ 'name':'Name',
+ 'type':'Type',
+ 'desc':'Description',
+ }
+ data = self._get_feature_api_data(self._config, columns)
+ data.sort(key=lambda item: item['fqr'])
+ return {'columns' : columns,
+ 'data' : data}
+
+ @classmethod
+ def _get_feature_api_data(cls, config, column_dict):
+ # Traverse through all features in the api
+ # and construct the data rows
+ data = []
+ storageroot = os.path.abspath(config.get_storage().get_path())
+ for elem in config.get_default_view().get_features('**'):
+ elemfile = os.path.join(storageroot,elem._obj.find_parent(type=api.Configuration).get_full_path())
+ #print "elemfile %s " % elemfile
+ featurerow = {'file': elemfile}
+
+ for col in column_dict:
+ try:
+ featurerow[col] = getattr(elem,col) or ''
+ except AttributeError,e:
+ #logging.getLogger('cone').warning('Could not find attribute %s from %s' % (col, elem.fqr))
+ featurerow[col] = ''
+ data.append(featurerow)
+ return data
+
+
+class ImplDataProvider(ReportDataProviderBase):
+ def __init__(self, config, impl_filters):
+ self._config = config
+ self._impl_filters = impl_filters
+
+ def generate_data(self):
+ impl_set = plugin.filtered_impl_set(self._config, [self._impl_filters or '.*'])
+ return impl_set.get_all_implementations()
+
+
+class ContentDataProvider(ReportDataProviderBase):
+ def __init__(self, config):
+ self._config = config
+
+ def generate_data(self):
+ class Entry(object):
+ pass
+ data = []
+ layered_content = self._config.layered_content()
+ for ref in sorted(layered_content.list_keys()):
+ entry = Entry()
+ entry.file = ref
+ entry.actual_files = layered_content.get_values(ref)
+ data.append(entry)
+ return data
+
+
+class ValueDataProvider(ReportDataProviderBase):
+
+ class FeatureGroup(object):
+ def __init__(self, name, features):
+ self.name = name
+ self.features = features
+
+ class Feature(object):
+ def __init__(self, **kwargs):
+ self.ref = kwargs['ref']
+ self.name = kwargs['name']
+ self.type = kwargs['type']
+ self.desc = kwargs['desc']
+ self.options = kwargs['options']
+
+ class Config(object):
+ def __init__(self, path, values):
+ self.path = path
+ self.values = values
+
+ class SequenceColumn(object):
+ def __init__(self, ref, name, type):
+ self.ref = ref
+ self.name = name
+ self.type = type
+
+ def __eq__(self, other):
+ if type(self) == type(other):
+ for varname in ('ref', 'name', 'type'):
+ if getattr(self, varname) != getattr(other, varname):
+ return False
+ return True
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ return "SequenceColumn(ref=%r, name=%r, type=%r)" \
+ % (self.ref, self.name, self.type)
+
+ class SequenceData(object):
+ def __init__(self, columns, rows):
+ self.columns = columns
+ self.rows = rows
+ self.is_sequence_data = True
+
+ def __eq__(self, other):
+ if type(self) == type(other):
+ for varname in ('columns', 'rows'):
+ if getattr(self, varname) != getattr(other, varname):
+ return False
+ return True
+ else:
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __repr__(self):
+ return "SequenceData(columns=%r, rows=%r)" \
+ % (self.columns, self.rows)
+
+
+ def __init__(self, configs, view):
+ assert len(configs) > 0, "configs must contain at least one configuration!"
+ self._configs = configs
+ self._view = view
+
+ def generate_data(self):
+ configs = self._configs
+ view = self._view
+
+ # Get the feature list from the first configuration
+ feature_groups = self._get_feature_groups(self._configs[0], view)
+
+ # Load setting values from all configurations
+ output_configs = [] # List of self.Config objects, not api.Configuration objects
+ for i, config in enumerate(self._configs):
+ print "Loading configuration %s (%d of %d)" % (config.get_path(), i + 1, len(self._configs))
+ dview = config.get_default_view()
+
+ values = {}
+ for group in feature_groups:
+ for entry in group.features:
+ try:
+ feature = dview.get_feature(entry.ref)
+ values[entry.ref] = self._resolve_value(feature)
+ except exceptions.NotFound:
+ pass
+
+ output_configs.append(self.Config(config.get_path(), values))
+
+ # Add a 'modified' attribute to all features
+ for group in feature_groups:
+ for feature in group.features:
+ modified = False
+ first_value_set = False
+ first_value = None
+ for output_config in output_configs:
+ if feature.ref not in output_config.values:
+ continue
+
+ if not first_value_set:
+ first_value = output_config.values[feature.ref]
+ first_value_set = True
+ else:
+ if output_config.values[feature.ref] != first_value:
+ modified = True
+ break
+
+ feature.modified = modified
+
+ return {'feature_groups' : feature_groups,
+ 'configs' : output_configs}
+
+ def _resolve_value(self, feature):
+ """
+ Resolve the value of the given feature (must be a data proxy).
+
+ @param feature: The feature whose value is to be resolved.
+ @return: The resolved value (value directly from the feature, name of a selection option,
+ or a SequenceData object.
+ """
+ assert isinstance(feature, api._FeatureDataProxy)
+
+ if isinstance(feature._obj, api.FeatureSequence):
+ return self._get_sequence_data(feature)
+
+ return self._resolve_option_value(feature, feature.get_value())
+
+ def _resolve_option_value(self, feature, value):
+ """
+ Resolve an option value for the given feature.
+
+ @param feature: The feature, can be a data proxy or the feature object itself.
+ @param value: The value to resolve.
+ @return: The resolved value; the name of the selected option if possible,
+ otherwise the value that was passed in.
+ """
+ if isinstance(feature, api._FeatureDataProxy):
+ feature = feature._obj
+
+ for option in self._get_options(feature):
+ if option.get_value() == value:
+ return option.get_name()
+
+ return value
+
+ def _get_sequence_data(self, seq_feature):
+ """
+ Return a SequenceData object based on the given sequence feature.
+ """
+ assert isinstance(seq_feature, api._FeatureDataProxy)
+ assert isinstance(seq_feature._obj, api.FeatureSequence)
+
+ sub_feature_objs = []
+ columns = []
+ for obj in seq_feature._obj._objects():
+ if isinstance(obj, api.Feature):
+ col = self.SequenceColumn(obj.ref, obj.name, obj.type)
+ columns.append(col)
+ sub_feature_objs.append(obj)
+
+ rows = []
+ for value_row in seq_feature.get_value():
+ row = {}
+ for index, value_item in enumerate(value_row):
+ ref = columns[index].ref
+ sub_feature = sub_feature_objs[index]
+ value = self._resolve_option_value(sub_feature, value_item)
+ row[ref] = value
+ rows.append(row)
+
+ return self.SequenceData(columns, rows)
+
+ def _get_feature_groups(self, config, view):
+ """
+ Return a list of FeatureGroup objects generated based on the given configuration and view.
+ @param configuration: The configuration to use.
+ @param view: The view to use. Can be None, in which case all features in the
+ configuration will be used.
+ """
+ feature_groups = []
+
+ if view is None:
+ feature_list = self._get_feature_list(config.get_default_view().get_features('**'))
+ feature_groups = [self.FeatureGroup('All settings', feature_list)]
+ else:
+ # Populate the view so that it contains the settings and
+ # get_features() can be used
+ config._add(view)
+ view.populate()
+
+ # Recursively collect a flattened list of all groups
+ def visit_group(group, name_prefix):
+ name = None
+
+ # Ignore the name for the view, record only group-level names
+ # (the view cannot directly contain settings according to the
+ # spec, they need to be inside a group)
+ if not isinstance(group, api.View):
+ if name_prefix: name = name_prefix + ' -- ' + group.get_name()
+ else: name = group.get_name()
+
+ # Add features if necessary
+ features = self._get_feature_list(group.get_features('*'))
+ if len(features) > 0:
+ feature_groups.append(self.FeatureGroup(name, features))
+
+ # Recurse to child groups
+ for child in group._objects():
+ if isinstance(child, api.Group):
+ visit_group(child, name)
+
+ visit_group(view, None)
+
+ return feature_groups
+
+ def _get_feature_list(self, feature_objects):
+ """
+ Return a list of feature data entries based on the given features.
+ @param feature_objects: List of api._FeatureDataProxy objects, e.g.
+ the output of api.Group.get_features().
+ @return: List of ValueDataProvider.Feature objects.
+ """
+ refs = set()
+ feature_list = []
+ for elem in feature_objects:
+ # Ignore elements with no type (they are not settings)
+ if not hasattr(elem, 'type') or elem.type in (None, ''):
+ continue
+
+ # For sequences don't include sub-settings, only the
+ # sequence settings themselves
+ feature = self._get_parent_sequence_or_self(elem._obj)
+ ref = feature.fqr
+
+ # Don't add if it's already in the list
+ if ref in refs: continue
+ else: refs.add(ref)
+
+ feature_data = self.Feature(
+ ref = ref,
+ name = feature.name,
+ type = feature.type,
+ desc = feature.desc,
+ options = self._get_options(feature))
+ feature_list.append(feature_data)
+ return feature_list
+
+ def _get_options(self, feature):
+ """
+ Return a list of api.Option objects for the given feature.
+ """
+ if isinstance(feature, api._FeatureDataProxy):
+ feature = feature._obj
+
+ options = []
+ for obj in feature._objects():
+ if isinstance(obj, api.Option):
+ options.append(obj)
+ return options
+
+ def _get_parent_sequence_or_self(self, feature):
+ """
+ Return the parent sequence of the given feature, or the feature
+ itself if it is not a sequence sub-setting.
+ """
+ current = feature._parent
+ while current is not None:
+ if isinstance(current, api.FeatureSequence):
+ return current
+ current = current._parent
+ return feature
+
+
+# ============================================================================
+# Helper functions
+# ============================================================================
+
+class ViewLoadError(RuntimeError):
+ """Exception raised if _load_view_from_file() fails"""
+ pass
+
+def _load_view_from_file(filename):
+ """
+ Load the first view from the given ConfML file.
+ @raise ViewLoadError: An error occurred when loading the file.
+ """
+ file_abspath = os.path.abspath(filename)
+ file_dir = os.path.dirname(file_abspath)
+ file_name = os.path.basename(file_abspath)
+
+ # Open the view file inside a "project" so that XIncludes are
+ # handled properly
+ try:
+ view_project = api.Project(FileStorage(file_dir, 'r'))
+ view_config = view_project.get_configuration(file_name)
+ views = view_config._traverse(type=api.View)
+ except Exception, e:
+ import traceback
+ logging.getLogger('cone').debug(traceback.format_exc())
+ raise ViewLoadError("Error parsing view ConfML file: %s" % e)
+
+ if len(views) == 0:
+ raise ViewLoadError("No views in specified view ConfML file '%s'" % filename)
+ elif len(views) == 1:
+ return views[0]
+ else:
+ print "Found %d view(s) in file '%s', using the last one" % (len(views), filename)
+ return views[-1]
+
+# ============================================================================
+
+if __name__ == "__main__":
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_merge.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_merge.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,412 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys
+import logging
+from optparse import OptionParser, OptionGroup
+import cone_common
+
+from cone.public import api, utils, exceptions
+
+VERSION = '1.0'
+
+logger = logging.getLogger('cone')
+
+class MergeFailedException(Exception):
+ """
+ Exception raised if the merge failed for some reason.
+ """
+ pass
+
+class MergePolicy(object):
+ """
+ Merge policy constants.
+ """
+ #: Replace/add files from the source layer into the
+ #: target layer, preserving files in the target layer
+ #: that do not exist in the source layer
+ REPLACE_ADD = 'replace-add'
+
+ #: Overwrite the entire target layer, so that it contains
+ #: only the contents of the source layer
+ OVERWRITE_LAYER = 'overwrite-layer'
+
+ ALL = (REPLACE_ADD, OVERWRITE_LAYER)
+
+ @classmethod
+ def is_valid(cls, policy):
+ return policy in cls.ALL
+
+def get_new_layer_name(oldname,rootconfig):
+ newpath = utils.resourceref.get_path(oldname)
+ newpath+= "_" + utils.resourceref.remove_ext(utils.resourceref.get_filename(rootconfig))
+ newpath+= "/" + utils.resourceref.get_filename(oldname)
+ return newpath
+
+def merge_configuration_layer(sourceconfig, targetconfig, merge_policy):
+ """
+ Merge the contents of the source layer into the target layer.
+ @param sourceconfig: Source layer root configuration object.
+ @param targetconfig: Target layer root configuration object.
+ @param merge_policy: The used layer merge policy.
+ """
+ # If policy tells to entirely overwrite the layer, remove all
+ # resources from the layer first
+ if merge_policy == MergePolicy.OVERWRITE_LAYER:
+ # Remove configurations from the layer root
+ confs = targetconfig.list_configurations()
+ for conf in confs:
+ targetconfig.remove_configuration(conf)
+
+ # Remove all related resources
+ layerobj = targetconfig.get_layer()
+ # Round one: remove all files
+ resources = layerobj.list_all_related(empty_folders=False)
+ for res in resources: layerobj.delete_resource(res)
+ # Round two: remove any remaining empty directories
+ resources = layerobj.list_all_related(empty_folders=True)
+ for res in resources: layerobj.delete_folder(res)
+
+ # Find all ConfML files
+ confml_resources = sourceconfig.list_configurations()
+
+ # Find all other related files and folders (content/, doc/ etc.)
+ layerobj = sourceconfig.get_layer()
+ targetobj = targetconfig.get_layer()
+ other_resources = layerobj.list_all_related(empty_folders=True)
+
+ # Copy the resources to the target configuration
+ for res_path in confml_resources + other_resources:
+ try:
+ rres = layerobj.open_resource(res_path,"rb")
+ wres = targetobj.open_resource(res_path,"wb")
+ print "Copying %s" % rres.path
+ logger.info('Copying layer resource %s to %s' % (rres.path, wres.path))
+ wres.write(rres.read())
+ wres.close()
+ rres.close()
+ except exceptions.NotResource:
+ # If it isn't a resource (file), it's a folder
+ targetobj.create_folder(res_path)
+
+ # Remove all configurations from the target layer root
+ already_included = targetconfig.list_configurations()
+ for confml_path in already_included:
+ targetconfig.remove_configuration(confml_path)
+
+ # Include them back
+ for confml_path in already_included:
+ targetconfig.include_configuration(confml_path)
+
+ # Include all added configurations
+ for confml_path in confml_resources:
+ if confml_path not in already_included:
+ print "Including %s in layer root %s" % (confml_path, targetconfig.path)
+ targetconfig.include_configuration(confml_path)
+
+def find_layers_to_merge(layer_indices, rename, sourceconfig, targetconfig):
+ """
+ Return a list of layers to merge.
+
+ @param layer_indices: List of layer indices to merge, can also be
+ None to indicate that all layers are to be merged.
+ @param rename: True if the layers should be renamed in the target
+ config, False if not.
+ @return: A list of tuples (layer_root, target_layer_root), where
+ layer_root is the path to the layer root in the source
+ configuration and target_layer_root the one in the target
+ configuration.
+ """
+ # Get a list of all configurations to merge
+ if layer_indices is None:
+ mergeconfigs = sourceconfig.list_configurations()
+ else:
+ mergeconfigs = sort_mergeconfigs(layer_indices, sourceconfig.list_configurations())
+
+ result = []
+ if rename:
+ for source_path in mergeconfigs:
+ target_path = get_new_layer_name(source_path, targetconfig.path)
+ result.append((source_path, target_path))
+ else:
+ for source_path in mergeconfigs:
+ result.append((source_path, source_path))
+
+ return result
+
+def sort_mergeconfigs(layers, sourceconfigs):
+ """
+ Return a correctly sorted list of source configuration layers.
+ @param layers: List of the indices of the layers to merg. Can be None, in
+ which case all layers are returned.
+ @param sourceconfigs: List of all configuration layer root paths in the
+ source project.
+ @return: List of configuration layer root paths.
+ """
+ sorted_configs = [None for _ in xrange(len(sourceconfigs))]
+ for layer in layers:
+ sorted_configs[layer]=sourceconfigs[layer]
+ sorted_configs = filter(lambda x: x != None, sorted_configs)
+ return sorted_configs
+
+def merge_config_root_to_config_root(source_project, target_project,
+ source_config, target_config,
+ layer_indices, rename,
+ merge_policy):
+ """
+ Merge the source configuration root to the target configuration root.
+ @param layer_indices: List of layer indices to specify the layers
+ to merge, can be None.
+ @param rename: If True, the merged layers are renamed based on the
+ name of the target configuration root.
+ @param merge_policy: The used merge policy.
+ """
+
+ def get_active_root_if_necessary(project, configuration, name):
+ if configuration:
+ return configuration
+ else:
+ active_root = project.get_storage().get_active_configuration()
+ if active_root == "":
+ raise MergeFailedException("No %s configuration given and the project does not have an active root" % name)
+ else:
+ return active_root
+
+ target_root = get_active_root_if_necessary(target_project, target_config, 'target')
+ source_root = get_active_root_if_necessary(source_project, source_config, 'source')
+
+ print "Target config: %s" % target_root
+ print "Source config: %s" % source_root
+
+ try:
+ source_config = source_project.get_configuration(source_root)
+ except exceptions.NotFound:
+ raise MergeFailedException("Configuration root '%s' not found in source project" % source_root)
+
+
+ # Create or get the target configuration root
+ try:
+ target_config = target_project.get_configuration(target_root)
+ except exceptions.NotFound:
+ logger.info('Creating new root configuration %s' % (target_config))
+ target_config = target_project.create_configuration(target_config)
+ for sourcelayer_path in source_config.list_configurations():
+ sourcelayer = source_config.get_configuration(sourcelayer_path)
+ sourcelayer_path = sourcelayer.path
+ if target_config.get_storage().is_resource(sourcelayer.path):
+ logger.info('Including layer %s to root %s' % (sourcelayer_path, target_config.path))
+ target_config.include_configuration(sourcelayer_path)
+ else:
+ logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path))
+ target_config.create_configuration(sourcelayer_path)
+
+ # Collect a correctly sorted list of all layer paths to merge
+ layers_to_merge = find_layers_to_merge(
+ layer_indices = layer_indices,
+ rename = rename,
+ sourceconfig = source_config,
+ targetconfig = target_config)
+
+ print "Merging %d layer(s)..." % len(layers_to_merge)
+
+ # Merge the layers
+ for source_path, target_path in layers_to_merge:
+ print "Merging %s -> %s" % (source_path, target_path)
+
+ source_layer = source_project.get_configuration(source_path)
+
+ if source_path != target_path:
+ try:
+ target_config.remove_configuration(source_path)
+ except exceptions.NotFound:
+ pass
+ target_config.create_configuration(target_path)
+
+ # Get or create the target configuration layer
+ try:
+ target_layer = target_config.get_configuration(target_path)
+ except exceptions.NotFound:
+ logger.info('Creating new layer configuration %s' % (target_path))
+ target_layer = target_config.create_configuration(target_path)
+
+ merge_configuration_layer(source_layer, target_layer, merge_policy)
+
+
+
+def main(argv=sys.argv):
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ parser.add_option("-c", "--configuration",\
+ dest="configuration",\
+ help="defines the name of the target configuration for the action",\
+ metavar="CONFIG")
+
+ parser.add_option("-p", "--project",\
+ dest="project",\
+ help="defines the location of current project. Default is the current working directory.",\
+ default=".",\
+ metavar="STORAGE")
+
+ group = OptionGroup(parser, 'Merge options',
+ 'The merge functionality is meant to merge configurations/layers '
+ 'from a remote project (defined with -r) to the current project (defined with -p). '
+ 'Default value for the current project is the currently working directory. '
+ 'A project can be either a folder or a cpf/zip file. There are two ways to '
+ 'use merge: merge configuration roots (multiple layers), or specific layers. '
+ 'See the ConE documentation for details and examples.')
+
+ group.add_option("-r", "--remote",\
+ dest="remote",\
+ help="defines the location of remote storage",\
+ metavar="STORAGE")
+
+ group.add_option("-s", "--sourceconfiguration",\
+ dest="sourceconfiguration",\
+ help="defines the name of the remote configuration inside the remote storage for the merge action. "\
+ "Default is the active root of the remote project.",\
+ metavar="CONFIG")
+
+ group.add_option("--sourcelayer",
+ help="Defines a specific layer to use as the layer to merge "\
+ "from the remote project. Must be the layer root (ConfML file)."\
+ "For example: --sourcelayer assets/somelayer/root.confml",
+ metavar="LAYER_ROOT",
+ default=None)
+
+ group.add_option("--targetlayer",
+ help="Defines a specific layer (root) to use as the layer to merge "\
+ "into the target project. Must be the layer root (ConfML file)."\
+ "For example: --targetlayer assets/somelayer/root.confml",
+ metavar="LAYER_ROOT",
+ default=None)
+
+ group.add_option("--rename",\
+ action="store_true",
+ dest="rename",\
+ help="defines that the merged layers need to be renamed",
+ default=False)
+
+ group.add_option("--all",\
+ action="store_true",
+ dest="all",\
+ help="Defines that the entire configuration (all layers) needs to be merged. "\
+ "This has no effect when merging layers directly using --sourcelayer and --targetlayer.",
+ default=False)
+
+ group.add_option("-l", "--layer",\
+ dest="layers",\
+ type="int",
+ action="append",
+ help="Define the layers of the source configuration that are included to merge action. "\
+ "The layer operation can be used several times in a single command. "\
+ "Note that this can only be used when merging configuration roots, not "\
+ "specific layers using --sourcelayer and --targetlayer. "\
+ "Example -l -1 --layer=-2, which would append a layers -1 and -2 to the layers => layers = -1,-2",
+ metavar="LAYERS",\
+ default=None)
+
+ group.add_option("--merge-policy",
+ help="Specifies the merge policy to use when merging layers. "\
+ "Possible values: "\
+ "replace-add - Add/replace files from source layer, but leave other files in the target as they are. "\
+ " "\
+ "overwrite-layer - Overwrite the entire layer (remove all previous content).",
+ default=MergePolicy.REPLACE_ADD)
+
+ parser.add_option_group(group)
+ (options, _) = parser.parse_args(argv)
+
+ cone_common.handle_common_options(options)
+
+ # Check the passed options
+ if not MergePolicy.is_valid(options.merge_policy):
+ parser.error("Invalid merge policy: %s\nMust be one of %s" % (options.merge_policy, '\n'.join(MergePolicy.ALL)))
+ if not options.remote: parser.error("Remote project must be given")
+ if options.layers and (options.sourcelayer or options.targetlayer):
+ parser.error("Specifying layer indices using --layer is not supported when using --sourcelayer or --targetlayer!")
+ if options.sourcelayer and not options.targetlayer:
+ parser.error("Merging a layer into a configuration is not supported at the moment!")
+ if options.sourcelayer and not options.sourcelayer.lower().endswith('.confml'):
+ parser.error("Source layer root should be a .confml file")
+ if options.targetlayer and not options.targetlayer.lower().endswith('.confml'):
+ parser.error("Target layer root should be a .confml file")
+ if not options.sourcelayer and options.targetlayer:
+ parser.error("Cannot merge a configuration into a layer!")
+
+ # If layers for configuration root merging are not specifically given,
+ # the default is the last layer
+ if options.layers is None:
+ options.layers = [-1]
+
+ target_project = api.Project(api.Storage.open(options.project,"a", username=options.username, password=options.password))
+ source_project = api.Project(api.Storage.open(options.remote,"r", username=options.username, password=options.password))
+
+ print "Target project: %s" % options.project
+ print "Source project: %s" % options.remote
+
+ target_config = None
+ try:
+ if options.sourcelayer and options.targetlayer:
+ print "Target layer: %s" % options.targetlayer
+ print "Source layer: %s" % options.sourcelayer
+
+ try:
+ source_config = source_project.get_configuration(options.sourcelayer)
+ except exceptions.NotFound:
+ raise MergeFailedException("Layer root '%s' not found in source project" % options.sourcelayer)
+
+ try:
+ target_config = target_project.get_configuration(options.targetlayer)
+ except exceptions.NotFound:
+ logger.info('Creating new layer %s' % (options.targetlayer))
+ target_config = target_project.create_configuration(options.targetlayer)
+
+ print "Merging layers..."
+ merge_configuration_layer(source_config, target_config, options.merge_policy)
+ else:
+ # Merging a configuration root into a configuration root
+
+ if options.all: layer_indices = None
+ else: layer_indices = utils.distinct_array(options.layers)
+
+ merge_config_root_to_config_root(
+ source_project = source_project,
+ target_project = target_project,
+ source_config = options.sourceconfiguration,
+ target_config = options.configuration,
+ layer_indices = layer_indices,
+ rename = options.rename,
+ merge_policy = options.merge_policy)
+ except MergeFailedException, e:
+ print "Could not merge: %s" % e
+ sys.exit(2)
+ else:
+ # Merge successful, so save the target configuration and project
+ # to persist the changes
+ if target_config: target_config.save()
+ target_project.save()
+
+ target_project.close()
+ source_project.close()
+
+
+if __name__ == "__main__":
+ main()
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_report.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_report.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,206 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import logging
+import pickle
+from optparse import OptionParser, OptionGroup
+import cone_common
+import generation_report
+from cone.public import api, plugin, utils, exceptions
+
+
+VERSION = '1.0'
+
+logger = logging.getLogger('cone')
+
+def main():
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ group = OptionGroup(parser, 'Report options',
+ 'The report function generates a report using previously generated '\
+ 'intermediary report data as input.')
+
+ group.add_option("-i", "--input-data",\
+ action="append",\
+ help="Defines an input file for report generation. "\
+ "If specified more than once, the data of all specified "\
+ "report data files is merged.",
+ metavar="FILE",
+ default=[])
+
+ group.add_option("-d", "--input-data-dir",\
+ help="Defines a directory containing the data files to use for "\
+ "generating the report. This is an alternative to specifying "\
+ "a number of --input-data files. The order of the data files "\
+ "is determined by the generation time stamps found in the data "\
+ "files.",
+ metavar="DIR",
+ default=None)
+
+ group.add_option("-r", "--report",\
+ dest="report",\
+ action="store",
+ type="string",
+ help="Specifies the report file to create."\
+ "Example -r report.html.",
+ metavar="FILE",\
+ default="report.html")
+
+ group.add_option("-t", "--template",\
+ dest="template",\
+ action="store",
+ type="string",
+ help="Template used in report generation."\
+ "Example -t report_template.html.",
+ metavar="FILE",\
+ default=None)
+
+ parser.add_option_group(group)
+ (options, args) = parser.parse_args()
+
+ cone_common.handle_common_options(options)
+
+ if len(options.input_data) == 0 and not options.input_data_dir:
+ parser.error("Input data must be specified with either --input-data or --input-data-dir")
+ if len(options.input_data) > 0 and options.input_data_dir:
+ parser.error("Both --input-data and --input-data-dir specified, use one or the other.")
+ if options.input_data_dir and not os.path.isdir(options.input_data_dir):
+ parser.error('Given --input-data-dir does not exist or is not a directory.')
+
+ if options.input_data:
+ files = options.input_data
+ else:
+ files = get_input_data_files(options.input_data_dir)
+
+ if len(files) == 0:
+ parser.error("At least one input data file must be specified.")
+
+
+ class DataEntry(object):
+ def __init__(self, label, data):
+ self.label = label
+ self.data = data
+
+ # Load all data files
+ data_entries = []
+ for data_file in files:
+ print "Loading data file '%s'" % data_file
+ label = get_generation_run_label(data_file)
+ data = generation_report.load_report_data(data_file)
+ data_entries.append(DataEntry(label, data))
+
+ # Sort by time stamp
+ data_entries.sort(key=lambda entry: entry.data.generation_timestamp)
+
+ # Use the first data object as the main report data
+ main_entry = data_entries[0]
+
+ # Merge the rest of the data objects into the main data
+ if len(data_entries) > 1:
+ # Update the generation_runs attribute of all implementations
+ # in the main data
+ for line in main_entry.data.lines:
+ for impl in line.impls:
+ impl.generation_runs = [main_entry.label]
+
+ # Load other report data files and merge them to the main data object
+ for i in xrange(len(data_entries) - 1):
+ entry = data_entries[i + 1]
+ print "Merging data for '%s'" % entry.label
+ merge_report_data(main_entry.data, entry.data, entry.label)
+
+ # Generate the report
+ main_entry.data.report_filename = options.report
+ generation_report.generate_report(main_entry.data, options.report, options.template)
+
+ print "Generated report to '%s'" % options.report
+
+def get_input_data_files(directory):
+ files = []
+ for name in os.listdir(directory):
+ path = os.path.join(directory, name)
+ if os.path.isfile(path):
+ files.append(path)
+ return files
+
+
+def get_generation_run_label(datafile_path):
+ filename = os.path.split(datafile_path)[1]
+ filename_noext = os.path.splitext(filename)[0]
+ return filename_noext
+
+def get_feature(rep_data, ref):
+ for feat in rep_data.lines:
+ if feat.ref == ref:
+ return feat
+ raise RuntimeError("Feature '%s' not found in refs with impl" % ref)
+
+def get_impl(rep_data, ref, impl_name):
+ feat = get_feature(rep_data, ref)
+ for impl in feat.impls:
+ if impl.name == impl_name:
+ return impl
+ raise RuntimeError("Impl '%s' not found for feature '%s'" % (impl_name, ref))
+
+def merge_report_data(data, data_to_merge, generation_run_label):
+ impls_by_ref = {}
+ for feat in data.lines:
+ impls_dict = {}
+ impls_by_ref[feat.ref] = impls_dict
+ for impl in feat.impls:
+ impls_dict[impl.name] = impl
+
+ for feat in data_to_merge.lines:
+ if feat.ref in impls_by_ref:
+ # Feature has implementations in both report data objects
+ # -------------------------------------------------------
+ impls_dict = impls_by_ref[feat.ref]
+
+ for impl in feat.impls:
+ if impl.name in impls_dict:
+ # Same implementation in both: add the generation run to merge to the impl
+ impl = get_impl(data, feat.ref, impl.name)
+ impl.generation_runs.append(generation_run_label)
+ else:
+ # Implementation only in the data to merge: add to the main data
+ impl = get_impl(data_to_merge, feat.ref, impl.name)
+ impl.generation_runs = [generation_run_label]
+ feat = get_feature(data, feat.ref)
+ feat.impls.append(impl)
+ feat.nbr_impls += 1
+ else:
+ # Feature has implementations only in the data to merge
+ # -----------------------------------------------------
+
+ # Add the feature and impls to the main data
+ feat = get_feature(data_to_merge, feat.ref)
+ for impl in feat.impls:
+ impl.generation_runs = [generation_run_label]
+ data.lines.append(feat)
+ data.nbr_of_refs += 1
+
+ # Remove from features with no impl in the main data
+ for i, noimpl_feat in enumerate(data.ref_noimpl):
+ if feat.ref == noimpl_feat.ref:
+ del data.ref_noimpl[i]
+ data.nbr_of_refs_noimpl -= 1
+ break
+
+if __name__ == "__main__":
+ main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/conesub_update.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_update.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,264 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import re
+import fnmatch
+import logging
+from optparse import OptionParser, OptionGroup
+
+import cone_common
+from cone.public import api, plugin, utils, exceptions
+
+
+VERSION = '1.0'
+DEFAULT_EXT = '.cpf'
+CPF_NAMESPACE = "http://www.nokia.com/xml/cpf-id/1"
+CPF_META_TAG = "configuration-property"
+
+logger = logging.getLogger('cone')
+
+def main():
+ parser = OptionParser(version="%%prog %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ parser.add_option("-c", "--configuration",
+ dest="configs",
+ action="append",
+ help="Defines the name of the configuration for the action, can be "\
+ "specified multiple times to include multiple configurations.",
+ metavar="CONFIG",
+ default=[])
+
+ parser.add_option("--config-wildcard",
+ action="append",
+ dest="config_wildcards",
+ help="Wildcard pattern for including configurations, e.g. "\
+ "product_langpack_*_root.confml",
+ metavar="WILDCARD",
+ default=[])
+
+ parser.add_option("--config-regex",
+ action="append",
+ dest="config_regexes",
+ help="Regular expression for including configurations, e.g. "\
+ "product_langpack_\\d{2}_root.confml",
+ metavar="REGEX",
+ default=[])
+
+ parser.add_option("-p", "--project",\
+ dest="project",\
+ help="defines the location of current project. Default is the current working directory.",\
+ default=".",\
+ metavar="STORAGE")
+
+ group = OptionGroup(parser, 'Update options',
+ 'The update functionality is meant for ConfML manipulation '
+ 'in current project (defined with -p). '
+ 'Default value for the current project is the currently working directory. '
+ 'A project can be either a folder or a cpf/zip file.')
+
+
+ group.add_option("-m","--add-meta",\
+ dest="meta",\
+ action="append",
+ type="string",
+ help="Add given metadata to defined configuration."\
+ "Example --add-meta \"owner=John Cone\" -m product=E75",
+ default=None)
+
+ group.add_option("--add-cpf-meta",\
+ dest="cpfmeta",\
+ action="append",
+ type="string",
+ help="Add given CPF identification metadata to defined configuration."\
+ "Example --add-cpf-meta \"coreplat_name=Platform1\"",
+ default=None)
+
+ group.add_option("-d","--add-desc",\
+ dest="desc",\
+ type="string",\
+ help="Add given description to defined configuration."\
+ "Example --add-desc \"Customer one CPF\" -d Description1",
+ default=None)
+
+ group.add_option("--remove-meta",\
+ dest="remove_meta",\
+ action="append",
+ type="string",
+ help="Removes given metadata from defined configuration."\
+ "Example --remove-meta owner --remove-meta coreplat_name",
+ metavar="META",\
+ default=None)
+
+ group.add_option("--remove-desc",\
+ dest="remove_desc",\
+ action="store_true",\
+ help="Removes description from defined configuration."\
+ "Example --remove-desc",
+ default=False)
+
+ group.add_option("--add-data",\
+ dest="data",\
+ action="append",
+ type="string",
+ help="Add given ConfML data to defined configuration."\
+ "Example --add-data \"KCRUidAvkon.KAknDefaultAppOrientation=1\"",
+ default=None)
+
+ parser.add_option_group(group)
+ (options, args) = parser.parse_args()
+
+ cone_common.handle_common_options(options)
+
+ # Open the project and find out the active configuration
+ project = api.Project(api.Storage.open(options.project, "a"))
+ try:
+ active_root = project.get_storage().get_active_configuration()
+ except AttributeError:
+ active_root = None
+
+ # Collect the list of configurations specified from the command line
+ config_list = []
+ if options.configs or options.config_wildcards or options.config_regexes:
+ try:
+ config_list = cone_common.get_config_list_from_project(
+ project = project,
+ configs = options.configs,
+ config_wildcards = options.config_wildcards,
+ config_regexes = options.config_regexes)
+ except cone_common.ConfigurationNotFoundError, e:
+ parser.error(str(e))
+
+ # Use the active configuration if no configurations are specifically given
+ if len(config_list) == 0:
+ if active_root is None:
+ parser.error("No configurations given and the project does not have an active root")
+ else:
+ logger.info('No configurations given! Using active root configuration %s' % active_root)
+ config_list = [active_root]
+
+
+
+ # Parse added meta and data definitions
+ added_meta = _parse_name_value_pairs(options.meta, 'metadata')
+ added_cpf_meta = _parse_name_value_pairs(options.cpfmeta, 'CPF metadata')
+ added_data = _parse_name_value_pairs(options.data, 'data')
+
+ for config_name in config_list:
+ print "Updating %s" % config_name
+ config = project.get_configuration(config_name)
+
+ # Handle metadata and data additions
+ if added_meta: _add_meta(config, added_meta)
+ if added_cpf_meta: _add_cpf_meta(config, added_cpf_meta)
+ if added_data: _add_data(config, added_data)
+
+ # Handle description
+ if options.desc:
+ logger.info("Setting description to %s" % options.desc)
+ config.desc = options.desc
+ if options.remove_desc:
+ if config.desc:
+ logger.info("Removing description")
+ del config.desc
+
+ # Handle metadata removals
+ if options.remove_meta:
+ for remove_meta in options.remove_meta:
+ if config.meta:
+ index = config.meta.find_by_tag(remove_meta)
+ if index != -1:
+ del config.meta[index]
+ logger.info("Removed %s" % remove_meta)
+ else:
+ index = config.meta.find_by_attribute("name", remove_meta)
+ if index != -1:
+ del config.meta[index]
+ logger.info("Removed %s" % remove_meta)
+ else:
+ logger.info("Could not remove metadata entry %s: not found." % remove_meta)
+
+ project.save()
+ project.close()
+
+def _parse_name_value_pairs(entries, entry_type_name):
+ """
+ Parse a list of 'name=value' pairs into a dictionary.
+ @param entries: The list of entries to parse.
+ @param entry_type_name: Entry type name shown in the error message if an entry
+ could not be parsed into a name-value pair.
+ """
+ if not entries:
+ return {}
+
+ result = {}
+ pattern = re.compile("(.+)=(.+)")
+ for entry in entries:
+ mo = pattern.search(entry)
+ if mo:
+ name = mo.group(1)
+ value = mo.group(2)
+ result[name] = value
+ else:
+ logger.error("Illegal %s definition: %s" % (entry_name, entry))
+ return result
+
+def _add_meta(config, added_meta):
+ if not config.meta:
+ config.meta = []
+
+ for tag, value in added_meta.iteritems():
+ index = config.meta.find_by_tag(tag)
+ if index != -1:
+ logger.info("Replacing %s's value %s with %s" % \
+ (tag, config.meta[index].value, value))
+ config.meta.replace(index, tag, value)
+ else:
+ logger.info("Adding value %s for %s." % (value, tag))
+ config.meta.add(tag, value)
+
+def _add_cpf_meta(config, added_cpf_meta):
+ if not config.meta:
+ config.meta = []
+ for attrName, attrValue in added_cpf_meta.iteritems():
+ index = config.meta.find_by_attribute("name", attrName)
+ if index != -1:
+ logger.info("Replacing %s's value %s with %s" % \
+ (attrName, config.meta[index].attrs["value"], attrValue))
+ config.meta.replace(index, CPF_META_TAG, None, CPF_NAMESPACE, {"name": attrName, "value": attrValue})
+ else:
+ logger.info("Adding value %s for %s." % \
+ (attrName, attrValue))
+ config.meta.add(CPF_META_TAG, None, CPF_NAMESPACE, {"name": attrName, "value": attrValue})
+
+def _add_data(config, added_data):
+ for ref, value in added_data.iteritems():
+ if value.startswith("["):
+ value = eval(value)
+ for value_item in value:
+ config.get_default_view().get_feature(ref).add_sequence(value_item, 0)
+ logger.info("Set %s=%s" % (ref, repr(value)))
+ else:
+ config.get_default_view().get_feature(ref).set_value(value)
+ logger.info("Set %s=%s" % (ref, value))
+
+if __name__ == "__main__":
+ main()
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/crml_dc_report_template.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/crml_dc_report_template.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,70 @@
+Modified:
+File,Repository UID,Repository name,Key UID,Key name,Changed value,Old value,New value
+{% for row in data.impl_data.flat.modified|sort -%}
+{#- Only report CRML changes (but ignore changes to key names, they don't matter for DC) -#}
+{%- if row.impl_type == 'crml' and row.value_id != 'name' -%}
+
+{# Ignore changes to read-only keys. However, if a key's read-only attribute is changed, that is reported. -#}
+{%- if 'target_key' not in row.data or row.data.target_key.read_only == false or row.data.source_key.read_only != row.data.target_key.read_only -%}
+
+{%- if 'target_key' in row.data -%}
+{% set key_name = row.data.target_key.name or row.data.source_key.name -%}
+{% else -%}
+{% set key_name = '' -%}
+{% endif -%}
+{%- set repo_name = row.data.target_repo.uid_name or row.data.source_repo.uid_name -%}
+{%- if repo_name == none -%}{%- set repo_name = '' -%}{%- endif -%}
+
+{{ row.file }},{{ row.id }},{{ repo_name }},{{ row.sub_id }},{{ key_name }},{{ row.value_id }},{{ row.source_value }},{{ row.target_value }}
+{% endif -%}
+
+{% endif -%}
+{% endfor %}
+
+Added:
+File,Repository UID,Repository name,Key UID,Key name
+{% for row in data.impl_data.flat.only_in_target|sort -%}
+{%- if row.impl_type == 'crml' and ('key' not in row.data or row.data.key.read_only == false) -%}
+{%- if row.data != none and 'key' in row.data -%}
+{%- set key_name = row.data.key.name -%}
+{%- else -%}
+{%- set key_name = '' -%}
+{%- endif -%}
+{%- set repo_name = row.data.repo.uid_name or '' -%}
+{{ row.file }},{{ row.id }},{{ repo_name }},{{ row.sub_id }},{{ key_name }}
+{% endif -%}
+{% endfor %}
+
+Removed:
+File,Repository UID,Repository name,Key UID,Key name
+{% for row in data.impl_data.flat.only_in_source|sort -%}
+{%- if row.impl_type == 'crml' and ('key' not in row.data or row.data.key.read_only == false) -%}
+{%- if row.data != none and 'key' in row.data -%}
+{%- set key_name = row.data.key.name -%}
+{%- else -%}
+{%- set key_name = '' -%}
+{%- endif -%}
+{%- set repo_name = row.data.repo.uid_name or '' -%}
+{{ row.file }},{{ row.id }},{{ repo_name }},{{ row.sub_id }},{{ key_name }}
+{% endif -%}
+{% endfor %}
+
+Duplicate repositories in source:
+File,Repository UID
+{% for row in data.impl_data.flat.duplicate|sort -%}
+{%- if row.impl_type == 'crml' -%}
+{% for file in row.files_in_source -%}
+{{ file }}{{row.impl_id}}
+{% endfor -%}
+{% endif -%}
+{% endfor %}
+
+Duplicate repositories in target:
+File,Repository UID
+{% for row in data.impl_data.flat.duplicate|sort -%}
+{%- if row.impl_type == 'crml' -%}
+{% for file in row.files_in_target -%}
+{{ file }}{{row.impl_id}}
+{% endfor -%}
+{% endif -%}
+{% endfor %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/crml_dc_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/crml_dc_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,152 @@
+{% extends "cone_base.html" %}
+{% block title %}Compare data{% endblock %}
+{% block content %}
+
+ CRML Data Compatibility Report
+
+
+
+ Source:
+ {{ data.sourcedata.name }}
+
+
+ Target:
+ {{ data.targetdata.name }}
+
+
+
+
+
+ Modified keys/files:
+
+
+
+ File
+ Repository UID
+ Repository name
+ Key UID
+ Key name
+ Changed value
+ Old value
+ New value
+
+
+ {% for row in data.impl_data.flat.modified|sort -%}
+ {#- Only report CRML changes (but ignore changes to key names, they don't matter for DC) -#}
+ {%- if row.impl_type == 'crml' and row.value_id != 'name' -%}
+ {# Ignore changes to read-only keys. However, if a key's read-only attribute is changed, that is reported. -#}
+ {%- if 'target_key' not in row.data or row.data.target_key.read_only == false or row.data.source_key.read_only != row.data.target_key.read_only -%}
+
+ {%- if 'target_key' in row.data -%}
+ {% set key_name = row.data.target_key.name or row.data.source_key.name -%}
+ {% else -%}
+ {% set key_name = '' -%}
+ {% endif -%}
+ {%- set repo_name = row.data.target_repo.uid_name or row.data.source_repo.uid_name -%}
+ {%- if repo_name == none -%}{%- set repo_name = '' -%}{%- endif -%}
+
+
+ {{ row.file }}
+ {{ row.id }}
+ {{ repo_name }}
+ {{ row.sub_id }}
+ {{ key_name }}
+ {{ row.value_id }}
+ {{ row.source_value }}
+ {{ row.target_value }}
+
+ {% endif -%}
+
+ {% endif -%}
+ {% endfor %}
+
+
+
+ Added keys/files:
+
+
+
+ File
+ Repository UID
+ Repository name
+ Key UID
+ Key name
+
+
+ {% for row in data.impl_data.flat.only_in_target|sort -%}
+ {%- if row.impl_type == 'crml' and ('key' not in row.data or row.data.key.read_only == false) -%}
+ {%- if row.data != none and 'key' in row.data -%}
+ {%- set key_name = row.data.key.name -%}
+ {%- else -%}
+ {%- set key_name = '' -%}
+ {%- endif -%}
+ {%- set repo_name = row.data.repo.uid_name or '' -%}
+
+
+ {{ row.file }}
+ {{ row.id or '' }}
+ {{ repo_name }}
+ {{ row.sub_id or '' }}
+ {{ key_name }}
+
+ {% endif -%}
+ {% endfor %}
+
+
+
+ Removed keys/files:
+
+
+
+ File
+ Repository UID
+ Repository name
+ Key UID
+ Key name
+
+
+ {% for row in data.impl_data.flat.only_in_source|sort -%}
+ {%- if row.impl_type == 'crml' and ('key' not in row.data or row.data.key.read_only == false) -%}
+ {%- if row.data != none and 'key' in row.data -%}
+ {%- set key_name = row.data.key.name -%}
+ {%- else -%}
+ {%- set key_name = '' -%}
+ {%- endif -%}
+ {%- set repo_name = row.data.repo.uid_name or '' -%}
+
+
+ {{ row.file }}
+ {{ row.id or '' }}
+ {{ repo_name }}
+ {{ row.sub_id or '' }}
+ {{ key_name }}
+
+ {% endif -%}
+ {% endfor %}
+
+
+
+ Duplicate repositories:
+
+
+
+ Repository UID
+ Files in source
+ Files in target
+
+
+ {% for row in data.impl_data.flat.duplicate|sort -%}
+ {%- if row.impl_type == 'crml' -%}
+
+ {{ row.id }}
+
+ {% for file in row.files_in_source %}{{ file }} {% endfor %}
+
+
+ {% for file in row.files_in_target %}{{ file }} {% endfor %}
+
+
+ {% endif -%}
+ {% endfor %}
+
+{% endblock %}
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/gen_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/gen_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,440 @@
+
+
+
+ ConE generation report
+
+
+
+
+ Generation summary:
+
+
+ Statistics
+
+
+ Refs in files
+ {{ rep_data.nbr_of_refs }}
+
+
+ Refs with no implementation
+ {{ rep_data.nbr_of_refs_noimpl }}
+
+
+ Details
+
+
+ Report generated
+ {{ rep_data.generation_time }}
+
+
+ Generation duration
+ {{ rep_data.duration }}
+
+
+ Generation log
+ cone.log
+
+
+ Generation options
+
+
+ Layers
+ {{ rep_data.options.layers }}
+
+
+ Added
+ {{ rep_data.options.added }}
+
+
+ Dryrun
+ {{ rep_data.options.dryrun }}
+
+
+ Verbose
+ {{ rep_data.options.verbose }}
+
+
+ Overrides
+ {{ rep_data.options.overrides }}
+
+
+ Project
+ {{ rep_data.options.project }}
+
+
+ Report
+ {{ rep_data.options.report }}
+
+
+ Impls
+ {{ rep_data.options.impls }}
+
+
+ Output
+ {{ rep_data.options.output }}
+
+
+ Configuration
+ {{ rep_data.options.configuration }}
+
+
+ Working directory
+ {{ rep_data.cwd }}
+
+
+
+ Rule execution results:
+
+
+
+ File
+ Rule No.
+ Input refs
+ Affected refs
+
+
+ {% for result in rep_data.rule_exec_results %}
+ {#- Report only rule executions that affected something #}
+ {%- if result.affected_refs|length > 0 %}
+
+
+ {{ result.source }}
+ {{result.index}}
+
+ {%- for ref in result.input_refs -%}
+ {{ref}}
+ {% endfor %}
+
+
+ {%- for ref in result.affected_refs -%}
+ {{ref}}
+ {% endfor %}
+
+
+ {% endif -%}
+ {% endfor %}
+
+
+
+
+ Output files:
+
+
+
+ API
+ Data
+ Impl. file
+ Impl. type
+ Generated for
+ Output files
+
+ {% for feat in rep_data.lines %}
+
+
+
+ {% if feat.is_temp_feature -%}
+ {{ feat.ref }}
+ {%- else -%}
+ {{ feat.ref }}
+ {%- endif %}
+ Name: {{ feat.feat_name }}
+ Type: {{ feat.feat_type }}
+ ConfML: {{ feat.config_path }}
+
+
+
+
+ {% for data in feat.datas %}
+ {% if loop.first %}
+
+
+
+
+
+ {{ data.layer }}
+ {{ data.value|e|xml_charref_replace }}
+
+ {% else %}
+
+ {{ data.layer }}
+ {{ data.value|e|xml_charref_replace }}
+
+ {% endif %}
+ {% endfor %}
+
+
+
+ {% for data in feat.seq_data %}
+ {% if loop.first %}
+
+
+
+
+
+ {{ data[0]|e|xml_charref_replace }}
+
+ {% for value in data[1] %}
+ {{ value|e|xml_charref_replace }}
+ {% endfor %}
+
+
+ {% else %}
+
+ {{ data[0]|e|xml_charref_replace }}
+
+ {% for value in data[1] %}
+ {{ value|e|xml_charref_replace }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% endfor %}
+
+
+ {% for impl in feat.impls %}
+ {% if loop.first %}
+
+ {{ impl.name }}
+
+
+ {{ impl.type }}
+
+
+ {{ ', '.join(impl.generation_runs) }}
+
+
+ {% for output in impl.outputfiles -%}
+ {% if output.exists %}
+ {{ output.filename }}
+ {% else %}
+ {{ output.filename }}
+ {% endif %}
+ {%- endfor %}
+
+ {% else %}
+
+
+ {{ impl.name }}
+
+
+ {{ impl.type }}
+
+
+ {{ ', '.join(impl.generation_runs) }}
+
+
+ {% for output in impl.outputfiles %}
+ {% if output.exists %}
+ {{ output.filename }}
+ {% else %}
+ {{ output.filename }}
+ {% endif %}
+ {% endfor %}
+
+
+ {% endif %}
+
+ {% endfor %}
+
+ {% endfor %}
+
+
+ Refs with no implementation:
+
+
+
+ API
+ Data
+
+ {% for feat in rep_data.ref_noimpl %}
+
+
+ {% if feat.is_temp_feature -%}
+ {{ feat.ref }}
+ {%- else -%}
+ {{ feat.ref }}
+ {%- endif %}
+ Name: {{ feat.feat_name|e|xml_charref_replace }}
+ Type: {{ feat.feat_type|e|xml_charref_replace }}
+ ConfML: {{ feat.config_path }}
+
+
+
+
+ {% for data in feat.datas %}
+ {% if loop.first %}
+
+
+
+
+
+ {{ data.layer }}
+ {{ data.value|e|xml_charref_replace }}
+
+ {% else %}
+
+ {{ data.layer }}
+ {{ data.value|e|xml_charref_replace }}
+
+ {% endif %}
+ {% endfor %}
+
+
+
+ {% for data in feat.seq_data %}
+ {% if loop.first %}
+
+
+
+
+
+ {{ data[0] }}
+
+ {% for value in data[1] %}
+ {{ value|e|xml_charref_replace }}
+ {% endfor %}
+
+
+ {% else %}
+
+ {{ data[0] }}
+
+ {% for value in data[1] %}
+ {{ value|e|xml_charref_replace }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% endfor %}
+
+
+ {% endfor %}
+
+ Not generated output files:
+
+
+
+ Output file
+
+ {% for file in rep_data.missing_output_files %}
+
+
+ {{ file.filename }}
+
+ {% endfor %}
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/generation_report.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/generation_report.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,315 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, logging, pickle
+import time
+from time import gmtime, strftime
+from jinja2 import Environment, PackageLoader, FileSystemLoader, Template
+from cone.public import api, exceptions, utils, plugin
+from cone.confml import model
+import report_util
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+def save_report_data(rep_data, file_path):
+ """
+ Save report data into an intermediary report data file.
+ """
+ dir = os.path.dirname(file_path)
+ if dir != '' and not os.path.exists(dir):
+ os.makedirs(dir)
+
+ pickle_data = pickle.dumps(rep_data)
+ f = open(file_path, 'wb')
+ try: f.write(pickle_data)
+ finally: f.close()
+
+def load_report_data(file_path):
+ """
+ Load report data from an intermediary report data file.
+ """
+ f = open(file_path, "rb")
+ try: data = f.read()
+ finally: f.close()
+
+ return pickle.loads(data)
+
+def _get_parent_sequence_or_self(feature):
+ current = feature._parent
+ while current is not None:
+ if isinstance(current, api.FeatureSequence):
+ return current
+ current = current._parent
+ return feature
+
+def collect_report_data(config, options, all_refs, impl_set, rule_exec_results):
+ """
+ Collect data for report generation.
+ """
+ impls = impl_set.get_all_implementations()
+ impls.sort(key=lambda impl: (impl.ref, impl.index))
+ rep_data = ReportData()
+
+ # Sort the rule results for unit testing purposes
+ rep_data.rule_exec_results = sorted(rule_exec_results, key=lambda e: (e.source, e.index))
+
+ # Collect a dictionary that maps refs shown in the report to a list of
+ # actual sub-refs used in the generation.
+ # This is done because for sequence settings only an entry for the main
+ # sequence setting is shown, but the actual refs used in generation point
+ # to the individual sub-settings (and possibly even under them).
+ # An example entry in the dictionary could be
+ # 'MyFeature.MySequence' : ['MyFeature.MySequence.Name',
+ # 'MyFeature.MySequence.File.localPath',
+ # 'MyFeature.MySequence.File.targetPath']
+ dview = config.get_default_view()
+ refs_dict = {}
+ for ref in all_refs:
+ try:
+ feature = dview.get_feature(ref)
+ except exceptions.NotFound:
+ logging.getLogger('cone.generation_report').warning("Feature for data ref not found: %s" % ref)
+ continue
+
+ feature = _get_parent_sequence_or_self(feature._obj)
+ ref_to_report = feature.fqr
+
+ if ref_to_report not in refs_dict:
+ refs_dict[ref_to_report] = []
+ refs_dict[ref_to_report].append(ref)
+
+# msg = []
+# for ref, sub_refs in refs_dict.iteritems():
+# msg.append("Ref: %s\nSub-refs:\n%s" % (ref, '\n'.join(sub_refs)))
+# logging.getLogger('cone').debug('\n--------------------------------------\n'.join(msg))
+
+ # Go through the refs and create report data entries
+ for ref in sorted(refs_dict.iterkeys()):
+ sub_refs = refs_dict[ref]
+
+ #print "Ref: %s" % ref
+ try:
+ feat = dview.get_feature(ref)
+
+ # Skip imaker-internal settings
+ if isinstance(feat._obj, model.ConfmlSetting):
+ try:
+ prop = feat.get_property('cone-report-ignore')
+ if prop.value.lower() in ('1', 'true'):
+ continue
+ except exceptions.NotFound:
+ pass
+
+ #print "Still %s" % ref
+
+ found_output = False
+ line = RefLine(ref, feat.get_type())
+
+ if plugin.is_temp_feature(feat):
+ line.is_temp_feature = True
+
+ if feat.get_type() == 'sequence':
+ for f in feat.list_all_features():
+ line.add_sequence(feat.get_feature(f).get_name(), feat.get_feature(f).get_value())
+ else:
+ if isinstance(feat.get_datas(), list):
+ for d in feat.get_datas():
+ line.add_data(d.find_parent(type=api.Configuration).get_full_path(), d.get_value())
+ else:
+ line.add_data(feat.get_data().find_parent(type=api.Configuration).get_full_path(), feat.get_value())
+
+
+ # Impl and output files
+ has_impl = False
+ for impl in impls:
+ # Check for implementations using the actual sub-refs
+ if impl.has_ref(sub_refs):
+ has_impl = True
+ line.add_impl(impl.ref, impl.IMPL_TYPE_ID, impl.list_output_files())
+ if has_impl: rep_data.add_line(line)
+ else: rep_data.add_ref_noimpl(line)
+
+
+ # For localPath and targetPath, the name should be the one from its parent file/folder setting
+ if isinstance(feat._obj, (model.ConfmlLocalPath, model.ConfmlTargetPath)):
+ name = feat._obj._parent.name
+ else:
+ name = feat.name
+
+ line.set_feat_name(name)
+ line.set_config_path( feat._obj.find_parent(type=api.Configuration).get_full_path())
+
+ except Exception, e:
+ utils.log_exception(logging.getLogger('cone'), 'Failed to collect data for report. Exception: %s' % e)
+
+ # create one list of not generated files
+ for myline in rep_data.lines:
+ for myimpl in myline.impls:
+ for output_file in myimpl.outputfiles:
+ if not output_file.exists and output_file not in rep_data.missing_output_files:
+ rep_data.missing_output_files.append(output_file)
+
+ rep_data.set_options(options)
+ rep_data.set_output_dir(options.output)
+ rep_data.update_nbr_of_refs()
+ rep_data.update_nbr_of_refs_noimpl()
+
+ return rep_data
+
+def generate_report(rep_data, report_file_path, template_file_path=None):
+ """
+ Generate a generation report based on the given report data.
+ @param rep_data: The report data.
+ @param report_file_path: Path to the report file to generate.
+ @param template_file_path: Path to the template file to use.
+ If None, the default template is used.
+ """
+ # Determine the template file and directory to use
+ if template_file_path is None:
+ template_file_path = os.path.join(ROOT_PATH, 'gen_report_template.html')
+
+ report_util.generate_report(template_file_path, report_file_path, {'rep_data' : rep_data})
+
+class ReportData(object):
+ """
+ Data object that stores all information used in report generation.
+ """
+
+ def __init__(self):
+ self.generation_timestamp = time.time()
+ self.generation_time = strftime("%d.%m.%Y %H:%M:%S")
+ self.options = None
+ self.lines = []
+ self.nbr_of_refs = 0
+ self.nbr_of_refs_noimpl = 0
+ self.cwd = os.getcwd()
+ self.ref_noimpl = []
+ self.duration = 0
+ self.output_dir = os.getcwd()
+ self.project_dir = ''
+ self.rule_exec_results = []
+ self.missing_output_files = []
+
+ def set_output_dir(self, dir):
+ self.output_dir = os.path.abspath(os.path.normpath(dir))
+
+ def add_line(self, line):
+ self.lines.append(line)
+
+ def set_duration(self, duration):
+ self.duration = duration
+
+ def set_options(self, options):
+ self.options = options
+ self.project_dir = os.path.abspath(options.project)
+
+ def set_report_filename(self, filename):
+ self.report_filename = filename
+
+ def add_ref_noimpl(self, ref):
+ self.ref_noimpl.append(ref)
+
+ def update_nbr_of_refs(self):
+ self.nbr_of_refs = len(self.lines)
+
+ def update_nbr_of_refs_noimpl(self):
+ self.nbr_of_refs_noimpl = len(self.ref_noimpl)
+
+ def __repr__(self):
+ return "ReportData(%s)" % [self.generation_timestamp,
+ self.generation_time,
+ self.options,
+ self.lines,
+ self.nbr_of_refs,
+ self.nbr_of_refs_noimpl,
+ self.cwd,
+ self.ref_noimpl,
+ self.duration,
+ self.output_dir,
+ self.project_dir,
+ self.rule_exec_results,
+ self.missing_output_files]
+
+class RefLine(object):
+ """
+ Data object that stores information for one ref in report generation.
+ """
+
+ def __init__(self, ref, type):
+ self.ref = ref
+ self.feat_type = type
+ self.feat_name = None
+ self.feat_value = None
+ self.config_path = None
+ self.impls = []
+ self.output = None
+ self.nbr_impls = 0
+ self.nbr_outputfiles = 0
+ self.datas = []
+ self.nbr_of_datas = 0
+ self.nbr_of_rows = 0
+ self.seq_data = []
+ self.is_temp_feature = False
+
+ def add_impl(self, impl_file, impl_type, outputfiles):
+ self.impls.append(ImplLine(impl_file, impl_type, outputfiles))
+ self.nbr_impls = len(self.impls)
+ self.nbr_outputfiles = len(outputfiles) + self.nbr_outputfiles
+
+ def add_data(self, layer, value):
+ self.datas.append(DataLine(layer,value))
+ self.nbr_of_datas = len(self.datas)
+
+ def add_sequence(self, subsetting, values):
+ self.seq_data.append([subsetting, values])
+
+ def set_feat_name(self, name):
+ self.feat_name = name
+
+ def set_feat_value(self, value):
+ self.feat_value = value
+
+ def set_config_path(self, filename):
+ self.config_path = os.path.normpath(filename)
+
+class ImplLine():
+ def __init__(self, impl_file, impl_type, outputfiles, generation_runs=[]):
+ self.name = os.path.normpath(impl_file)
+ self.type = impl_type
+ files = []
+
+ for outputfile in outputfiles:
+ files.append(Outputfile(outputfile))
+
+ self.outputfiles = files
+ self.generation_runs = generation_runs
+
+class Outputfile():
+ def __init__(self, filename):
+ self.filename = os.path.normpath(filename)
+ self.abs_filename = os.path.abspath(filename)
+ self.exists = os.path.isfile(self.abs_filename)
+
+ def __eq__(self, other):
+ if type(self) is type(other):
+ return self.filename == other.filename
+ else:
+ return False
+
+class DataLine():
+ def __init__(self, layer, value):
+ self.layer = os.path.normpath(layer)
+ self.value = value
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/imaker_variantdir.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/imaker_variantdir.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,41 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+# iMaker variantdir integration specific changes to the default cfg
+#
+
+# Sections for different plugins
+[CRML]
+output_subdir=content
+
+[GCFML]
+output_subdir=content
+
+[CONTENT]
+output_subdir=
+
+[IMAGEML]
+output_subdir=content
+
+[MAKEML]
+
+[RULEML]
+
+[ROFS2]
+all-layers = true
+
+[ROFS3 : ROFS2]
+layers = -1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/info_api_report_template.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/info_api_report_template.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+{% for item in data.api_data.columns %}{{ item }},{% endfor %}
+{% for row in data.api_data.data %}{% for colname in data.api_data.columns %}"{{ row[colname] }}",{% endfor %}
+{% endfor %}
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/info_api_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/info_api_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+{% extends "cone_base.html" %}
+{% block title %}API info{% endblock %}
+{% block content %}
+ Configuration API info
+
+
+
+ File
+ {% for item in data.api_data.columns %}
+ {{ data.api_data.columns[item] }}
+ {% endfor %}
+
+ {% for row in data.api_data.data %}
+ {% if row['type'] != '' %}
+
+ {{row['file']}}
+ {% for colname in data.api_data.columns %}
+ {{ row[colname]|replace('\n', ' ') }}
+ {% endfor %}
+
+ {% endif %}
+ {% endfor %}
+
+
+{% endblock %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/info_content_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/info_content_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,23 @@
+{% extends "cone_base.html" %}
+{% block title %}Content info{% endblock %}
+{% block content %}
+ Configuration content files
+
+
+
+ Content file
+ Actual files (used one last)
+
+ {% for entry in data.content_data %}
+
+ {{ entry.file }}
+
+ {%- for file in entry.actual_files -%}
+ {{file}}
+ {%- endfor -%}
+
+
+ {% endfor %}
+
+
+{% endblock %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/info_impl_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/info_impl_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,40 @@
+{% extends "cone_base.html" %}
+{% block title %}Implementation info{% endblock %}
+{% block content %}
+ Implementations
+
+
+
+ File
+ Index
+ Type
+ Phase
+ Tags
+ Refs
+
+ {% for impl in data.impl_data %}
+
+ {{ impl.ref }}
+ {{ impl.index }}
+ {{ impl.IMPL_TYPE_ID }}
+ {{ impl.invocation_phase() }}
+
+ {%- for name, value in impl.get_tags().iteritems() -%}
+ {{name}} = {{value}}
+ {%- endfor -%}
+
+
+ {%- set refs = impl.get_refs() -%}
+ {%- if refs == None -%}
+ None
+ {%- else -%}
+ {%- for ref in refs -%}
+ {{ref}}
+ {%- endfor -%}
+ {%- endif -%}
+
+
+ {% endfor %}
+
+
+{% endblock %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/info_value_report_template.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/info_value_report_template.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+{#- Note: The empty comments are used for removing line feeds -#}
+Name,Type,Possible values,{% for config in data.value_data.configs %}{{ config.path | csv_escape }},{% endfor %}
+{# -#}
+{% for feature_group in data.value_data.feature_groups %}
+{{ feature_group.name }}
+{% for feature in feature_group.features -%}
+{{ feature.name | csv_escape }},{{ feature.type | csv_escape }},{#- -#}
+"{%- for option in feature.options -%}
+ {{- option.get_name() | csv_escape_partial }}
+{% endfor -%}",
+
+{%- for config in data.value_data.configs -%}
+ {%- if feature.ref in config.values -%}
+ {%- set value = config.values[feature.ref] -%}
+ {%- else -%}
+ {%- set value = "" -%}
+ {%- endif -%}
+ {%- if value.is_sequence_data -%}
+ ,
+ {%- else -%}
+ {{ value | csv_escape }},
+ {%- endif -%}
+{%- endfor %}
+{% endfor -%}
+{%- endfor %}
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/info_value_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/info_value_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,59 @@
+{% extends "cone_base.html" %}
+{% block title %}Data value info{% endblock %}
+{% block content %}
+ Configuration data value info
+
+
+
+ Name
+ Type
+ Possible values
+ {% for config in data.value_data.configs %}
+ {{ config.path }}
+ {% endfor %}
+
+ {% for feature_group in data.value_data.feature_groups %}
+ {{ feature_group.name }}
+ {% for feature in feature_group.features %}
+ {% if feature.modified %}{% else %} {% endif %}
+ {{ feature.name }}
+ {{ feature.type }}
+
+ {%- for option in feature.options -%}
+ {{ option.get_name() }}
+ {% endfor -%}
+
+
+ {% for config in data.value_data.configs -%}
+ {%- if feature.ref in config.values -%}
+ {%- set value = config.values[feature.ref] %}
+ {% else -%}
+ {%- set value = "" %}
+ {% endif -%}
+
+ {%- if value.is_sequence_data -%}
+ {% if value.rows|length > 0 %}
+
+ {%- for row in value.rows -%}
+ Item {{ loop.index }}
+ {%- for column in value.columns -%}
+
+ {{ column.name }}
+ {{ row[column.ref] }}
+
+ {%- endfor -%}
+ {%- endfor -%}
+
+ {% endif %}
+ {%- else -%}
+ {{- value -}}
+ {%- endif -%}
+
+ {% endfor %}
+
+
+ {% endfor -%}
+ {% endfor %}
+
+
+{% endblock %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/logging.ini
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/logging.ini Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,42 @@
+[DEFAULT]
+
+[loggers]
+keys=root,cone
+
+[handlers]
+keys=fileHandler,consoleHandler
+
+[formatters]
+keys=fileFormatter,consoleFormatter
+
+[logger_root]
+# Explicitly define level, since otherwise the default level would be used
+level=NOTSET
+handlers=fileHandler,consoleHandler
+
+[logger_cone]
+level=NOTSET
+qualname=cone
+handlers=
+
+[handler_consoleHandler]
+class=StreamHandler
+formatter=consoleFormatter
+args=(sys.stdout,)
+# level is not defined here , since it is expected to come from the defaults,
+# which in turn comes from the command line
+
+[handler_fileHandler]
+class=FileHandler
+level=DEBUG
+formatter=fileFormatter
+args=('%(logfile)s','w')
+
+[formatter_consoleFormatter]
+format=%(levelname)-8s: %(name)s
+ %(message)s
+datefmt=%m-%d %H:%M
+
+[formatter_fileFormatter]
+format=%(asctime)s %(levelname)-8s: %(name)s
+ %(message)s
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/report_util.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/report_util.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,190 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import urllib
+import logging
+from jinja2 import Environment, FileSystemLoader, Template
+from cone.public import utils
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+log = logging.getLogger('cone.report_util')
+
+class ReportShortcut(object):
+ def __init__(self, template_file, report_file, description):
+ self.template_file = template_file
+ self.report_file = report_file
+ self.description = description
+
+class ReportShortcutContainer(object):
+ """
+ Container for report shortcuts.
+
+ A report shortcut describes a pre-defined report option that
+ has a default template, report file and description. The shortcut
+ container holds a set of shortcuts and can be used to generate
+
+ """
+ def __init__(self, shortcuts, default_shortcut):
+ """
+ @param shortcuts: The shortcuts, a dictionary mapping shortcut
+ names to ReportShortcut objects.
+ @param default_shortcut: The default shortcut name to use
+ """
+ if not isinstance(shortcuts, dict):
+ raise ValueError("'shortcuts' must a dictionary (%s given)!" % type(shortcuts))
+ if default_shortcut is not None and default_shortcut not in shortcuts:
+ raise ValueError("'default_shortcut' must be either None or exist ing 'shortcuts'!")
+ self.shortcuts = shortcuts
+ self.default_shortcut = default_shortcut
+
+ def get_shortcut_help_text(self):
+ """
+ Create the text to append to the option description for the
+ option used to specify the used shortcut.
+ """
+ shortcuts_text = []
+ refs = sorted(self.shortcuts.keys())
+ if refs:
+ for ref in refs:
+ sc = self.shortcuts[ref]
+ text = "%s - %s" % (ref, sc.description)
+ COLUMN_WIDTH = (80 - 25)
+ space_count = COLUMN_WIDTH - (len(text) % COLUMN_WIDTH)
+ shortcuts_text.append(text + space_count * ' ')
+ else:
+ shortcuts_text.append("None")
+ shortcuts_text = '\n'.join(shortcuts_text)
+ return shortcuts_text
+
+ def is_valid_shortcut(self, shortcut):
+ """
+ Return whether the given shortcut is valid within the context
+ of this container.
+ """
+ return shortcut is None or shortcut in self.shortcuts
+
+ def determine_template_and_report(self, shortcut, template_file, report_file, report_file_name_without_ext):
+ """
+ Determine the actual template and report files based on the shortcuts
+ and given options.
+ @param shortcut: The used shortcut or None.
+ @param template_file: Explicitly given template file or None.
+ @param report_file: Explicitly given report file or None.
+ @param report_file_name_without_ext: Prefix used to determine the
+ report file name if the template was explicitly given, but the
+ report file was not. E.g. if this is 'test' and the explicitly
+ given template file is 'my_template.html', the report file would
+ be 'test.html'.
+ @return: Tuple (template_file, report_file) specifying the actual
+ template and report files.
+ """
+ actual_shortcut = None
+ actual_template_file = None
+ actual_report_file = None
+
+ # Handle report shortcut (set to default or check the given one)
+ if not shortcut:
+ actual_shortcut = self.default_shortcut
+ else:
+ actual_shortcut = shortcut
+
+ # Determine template file
+ if template_file:
+ actual_template_file = template_file
+ else:
+ actual_template_file = self.shortcuts[actual_shortcut].template_file
+
+ # Determine report output file
+ if report_file:
+ actual_report_file = report_file
+ else:
+ if template_file:
+ # Determine report file name based on the template file name
+ # if the template was explicitly given
+ actual_report_file = report_file_name_without_ext + os.path.splitext(template_file)[1]
+ else:
+ actual_report_file = self.shortcuts[actual_shortcut].report_file
+
+ return actual_template_file, actual_report_file
+
+def generate_report(template_file, report_file, report_data):
+ """
+ Generate a report based on the given template file, report file
+ and data dictionary.
+ @param template_file: Path to the template file to use.
+ @param report_file: Path to the output report file.
+ @param report_data: The report data dictionary used when rendering
+ the report from the template.
+ @return: True if successful, False if not.
+ """
+ log.debug('generate_report(template_file=%r, report_file=%r, )' % (template_file, report_file))
+ if not isinstance(report_data, dict):
+ raise ValueError("report_data must be a dictionary!")
+
+ try:
+ template_file = os.path.abspath(template_file)
+
+ loader = FileSystemLoader([os.path.dirname(template_file), ROOT_PATH])
+ env = Environment(loader=loader)
+ _set_default_filters(env)
+
+ template = env.get_template(os.path.basename(template_file))
+ file_string = template.render(report_data)
+
+ # Create directories for the report
+ report_dir = os.path.dirname(report_file)
+ if report_dir != '' and not os.path.exists(report_dir):
+ os.makedirs(report_dir)
+
+ # Write the rendered report to file
+ f = open(report_file, 'wb')
+ try: f.write(file_string.encode('utf-8'))
+ finally: f.close()
+
+ print "Generated report to '%s'" % report_file
+ return True
+ except Exception, e:
+ utils.log_exception(log, "Failed to generate report: %s %s" % (type(e), e))
+ return False
+
+def _set_default_filters(env):
+ """
+ Set default filters to the given Jinja environment
+ """
+ env.filters['xml_charref_replace'] = lambda value: unicode(value).encode('ascii', 'xmlcharrefreplace')
+ env.filters['pathname_to_url'] = lambda value: urllib.pathname2url(value)
+ env.filters['csv_escape'] = _csv_escape
+ env.filters['csv_escape_partial'] = lambda value: unicode(value).replace('"', '""')
+
+def _csv_escape(value):
+ """
+ Escape a string value so that it can be used as a field in a CSV file.
+ """
+ value = unicode(value)
+
+ needs_quoting = False
+ for special_char in '",\n':
+ if special_char in value:
+ needs_quoting = True
+
+ if needs_quoting:
+ if '"' in value:
+ value = value.replace('"', '""')
+ value = '"' + value + '"'
+
+ return value
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from pkg_resources import require
+require("setuptools")
+from setuptools import setup, find_packages
+
+datafiles = ['gen_report_template.html',
+ 'cone_defaults.cfg',
+ 'conesub_generate.cfg',
+ 'imaker_variantdir.cfg',
+ 'logging.ini',
+ 'cone_base.html',
+ 'compare_api_report_template.html',
+ 'compare_data_report_template.html',
+ 'info_api_report_template.csv',
+ 'info_api_report_template.html',
+ 'info_impl_report_template.html',
+ 'info_content_report_template.html',
+ 'info_value_report_template.html',
+ 'info_value_report_template.csv',
+ 'crml_dc_report_template.csv',
+ 'crml_dc_report_template.html']
+
+setup(
+ name = "cone-scripts",
+ version = '1.0',
+ scripts = ['cone_tool.py',
+ 'cone_common.py',
+ 'cone_subaction.py',
+ 'conesub_info.py',
+ 'conesub_export.py',
+ 'conesub_generate.py',
+ 'conesub_merge.py',
+ 'conesub_compare.py',
+ #'conesub_import_browserbookmarks.py',
+ 'conesub_update.py',
+ 'conesub_report.py',
+ 'generation_report.py',
+ 'report_util.py'] +
+ datafiles,
+
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine scripts",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone. scripts",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = False
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,72 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../..'))
+PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(SOURCE_ROOT, 'plugins'))
+assert os.path.split(SOURCE_ROOT)[1] == 'source'
+assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
+
+def _setup():
+ """
+ Set up everything so that running "python cone_tool.py" finds the ConE
+ and plug-in modules.
+ """
+ sys.path.append(SOURCE_ROOT)
+ sys.path.append(os.path.join(SOURCE_ROOT, 'testautomation'))
+
+ # Import the plugin_utils module from plugins/
+ sys.path.append(PLUGIN_SOURCE_ROOT)
+ import plugin_utils
+ del sys.path[-1]
+
+ # Collect all needed plug-in source directories (all in 'common')
+ plugin_sources = plugin_utils.find_plugin_sources(os.path.join(PLUGIN_SOURCE_ROOT, 'common'))
+ plugin_source_paths = [path for path, _ in plugin_sources]
+
+ paths = []
+ paths.append(SOURCE_ROOT)
+ paths.extend(plugin_source_paths)
+ os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + ';'.join(paths)
+
+ # Generate egg-info for the plug-ins if necessary
+ import build_egg_info
+ for path in plugin_source_paths:
+ build_egg_info.generate_egg_info(path)
+
+_setup()
+
+# Find all unittest_*.py files in this folder
+import re
+__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
+# Strip .py endings
+__all__ = map(lambda name: name[:-3], __all__)
+
+def collect_suite():
+ suite = unittest.TestSuite()
+ for test_module in __all__:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/export_standalone/export_standalone.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/export_standalone/export_standalone.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,132 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, shutil, imp
+from optparse import OptionParser
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
+PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(SOURCE_ROOT, 'plugins'))
+assert os.path.split(SOURCE_ROOT)[1] == 'source'
+assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
+
+sys.path.append(os.path.normpath(os.path.join(SOURCE_ROOT, 'testautomation')))
+import testautomation
+from testautomation.copy_dir import copy_dir
+
+def build_egg(dir, target_dir):
+ orig_workdir = os.getcwd()
+ os.chdir(dir)
+ try:
+ os.system('python setup.py bdist_egg --dist-dir "%s"' % target_dir)
+ finally:
+ os.chdir(orig_workdir)
+
+def read_export_function_from_file(file_path):
+ if not os.path.exists(file_path):
+ return None
+
+ m = imp.load_source(
+ file_path.replace('\\', '__')
+ .replace('/', '__')
+ .replace(':', '_')
+ .replace('.', '_')
+ .replace(' ', '_'),
+ file_path)
+
+ try:
+ return m.export_standalone
+ except AttributeError:
+ return None
+
+def main(argv):
+ # Parse args
+ parser = OptionParser()
+ parser.add_option("--target-dir",
+ help="The directory where the test are to be exported.",
+ metavar="COMMAND")
+ parser.add_option("--plugin-subpackage",\
+ help="The plug-in package for exporting plug-in integration tests.",\
+ default=None,\
+ metavar="SUBPACKAGE")
+ (options, args) = parser.parse_args()
+ if options.target_dir is None:
+ parser.error("Target directory must be given")
+ if options.plugin_subpackage is None:
+ parser.error("Plug-in sub-package name must be given")
+
+ TARGET_PATH = options.target_dir
+ PLUGIN_PACKAGES = ['common']
+ if options.plugin_subpackage.lower() not in ('', 'common'):
+ PLUGIN_PACKAGES.append(options.plugin_subpackage)
+
+ print "(Re)creating dir '%s'..." % TARGET_PATH
+ if os.path.exists(TARGET_PATH):
+ shutil.rmtree(TARGET_PATH)
+ os.makedirs(TARGET_PATH)
+
+
+ print "Copying script test files..."
+ copy_dir(source_dir = os.path.join(ROOT_PATH, '..'),
+ target_dir = os.path.join(TARGET_PATH, 'tests'),
+ dir_ignore_functions = [lambda d: d in ('.svn', 'temp', 'export_standalone')],
+ file_ignore_functions = [lambda f: f == 'cone.log' or f.endswith('.pyc')])
+
+ print "Copying plug-in integration test files..."
+ for name in PLUGIN_PACKAGES:
+ print " Processing plug-in package '%s'..." % name
+
+ package_path = os.path.join(PLUGIN_SOURCE_ROOT, name)
+ if not os.path.isdir(package_path):
+ print " '%s' does not exist or is not a directory!" % package_path
+ return 1
+
+ tests_path = os.path.join(package_path, 'integration-test')
+ if not os.path.isdir(tests_path):
+ print " No 'integration-test' directory, skipping"
+ continue
+
+ print " Copying test files..."
+ target_path = os.path.join(TARGET_PATH, 'plugin-tests', name + '_tests')
+ copy_dir(source_dir = tests_path,
+ target_dir = target_path,
+ dir_ignore_functions = [lambda d: d in ('.svn', 'temp')],
+ file_ignore_functions = [lambda f: f in ('cone.log', 'export_standalone.py') or f.endswith('.pyc')])
+
+ print " Overwriting __init__.py..."
+ f = open(os.path.join(target_path, '__init__.py'), 'wb')
+ f.close()
+
+ print " Exporting extra data..."
+ func = read_export_function_from_file(os.path.join(tests_path, 'export_standalone.py'))
+ if func:
+ print " Executing export function..."
+ func(target_path)
+
+ print "Copying overlay files..."
+ copy_dir(source_dir = os.path.join(ROOT_PATH, "overlay"),
+ target_dir = TARGET_PATH,
+ dir_ignore_functions = [lambda d: d == '.svn'])
+
+
+ print "Building eggs..."
+ eggs_dir = os.path.join(TARGET_PATH, 'eggs')
+ build_egg(os.path.join(SOURCE_ROOT), eggs_dir)
+ build_egg(os.path.join(SOURCE_ROOT, 'testautomation'), eggs_dir)
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/export_standalone/overlay/readme.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/export_standalone/overlay/readme.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+ConE automated basic acceptance tests
+-------------------------------------
+
+Execution steps:
+1. Extract the ConE release to test under cone/
+2. Execute runtests.cmd
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/export_standalone/overlay/runtests.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/export_standalone/overlay/runtests.cmd Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+
+python %~dp0%\runtests.py
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/export_standalone/overlay/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/export_standalone/overlay/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,91 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, re, unittest
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+CONE_PATH = os.path.join(ROOT_PATH, 'cone')
+EGGS_PATH = os.path.join(ROOT_PATH, 'eggs')
+
+def add_eggs_to_path(egg_path):
+ if not os.path.isdir(egg_path):
+ return
+
+ for name in os.listdir(egg_path):
+ if name.endswith('.egg'):
+ path = os.path.normpath(os.path.join(egg_path, name))
+ if path not in sys.path:
+ print "Adding '%s' to path" % name
+ sys.path.append(path)
+
+
+def collect_test_suite(base_dir, module_subdir, cone_cmd):
+ # Check that the directory exists
+ module_dir = os.path.join(base_dir, module_subdir)
+ if not os.path.exists(module_dir):
+ raise RuntimeError("'%s' does not exist!" % module_dir)
+
+ # Collect the names of all test modules (of the form "unittest_*.py")
+ test_modules_names = []
+ for name in os.listdir(module_dir):
+ if re.match(r'^unittest_.*\.py$', name) != None:
+ test_modules_names.append(name[:-3])
+
+ # Import the modules
+ sys.path.insert(0, base_dir)
+ try:
+ suite = unittest.TestSuite()
+ for modname in test_modules_names:
+ # Load the test module dynamically and add it to the test suite
+ top_module = __import__(module_subdir + '.' + modname)
+
+ # top_module contains now actually e.g. mymodule.unittest_sometest,
+ # so get the actual unit test module
+ module = getattr(top_module, modname)
+
+ module.CONE_CMD = cone_cmd
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+ finally:
+ del sys.path[0]
+
+def main():
+ CONE_CMD = os.path.join(CONE_PATH, 'cone.cmd')
+ if not os.path.exists(CONE_CMD):
+ print "cone.cmd not detected under '%s', exiting..." % CONE_PATH
+ return 0
+
+ add_eggs_to_path(EGGS_PATH)
+
+ suite = unittest.TestSuite()
+
+ # Collect script test suite
+ suite.addTest(collect_test_suite(ROOT_PATH, 'tests', CONE_CMD))
+
+ # Collect test suites from the plugin-tests/ directory
+ PLUGIN_TEST_DIR = os.path.join(ROOT_PATH, 'plugin-tests')
+ if os.path.exists(PLUGIN_TEST_DIR):
+ for name in os.listdir(PLUGIN_TEST_DIR):
+ plugin_suite = collect_test_suite(PLUGIN_TEST_DIR, name, CONE_CMD)
+ suite.addTest(plugin_suite)
+
+ # Run the tests
+ unittest.TextTestRunner(verbosity=2).run(suite)
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main())
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/export_standalone/overlay/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/export_standalone/overlay/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/export_test_project.zip
Binary file configurationengine/source/scripts/tests/export_test_project.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/.project
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/.project Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,24 @@
+
+
+ test_project
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerBuilder
+
+
+
+
+ com.nokia.s60ct.build.CenRepBuilder
+
+
+
+
+
+ com.nokia.tools.variant.confml.core.ConfMLLayerNature
+ com.nokia.s60ct.build.CenRepNature
+ com.nokia.s60ct.build.CenRepNature
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/confml/basic_setting_types_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/confml/basic_setting_types_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,46 @@
+
+
+
+ Feature with basic setting types (ConfML v2.0)
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/confml/feature2.confml
Binary file configurationengine/source/scripts/tests/generation_test_project/base/confml/feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/confml/file_folder_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/confml/file_folder_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+
+
+
+ Feature with file and folder setting types
+
+ A folder setting
+
+
+
+
+ A file setting
+
+
+
+
+
+
+
+ default_folder
+ default_target_folder/
+
+
+ default_file.txt
+ default_target_folder/default_file_renamed.txt
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/confml/multiselection.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/confml/multiselection.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+ Multi-selection test feature (ConfML v2.0)
+
+ A multi-selection setting
+
+
+
+
+
+
+
+
+
+
+
+ "opt 1" "opt 3"
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/confml/name_id_mapping_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/confml/name_id_mapping_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Entry 1
+ Entry 2
+ Entry 3
+
+
+
+
+
+ Entry 1 100
+ Entry 2 120
+ Entry 3 130
+
+
+
+
+
+
+ Entry 1 1.1
+ Entry 2 1.2
+ Entry 3 1.3
+
+
+
+
+
+ 0
+ 0
+
+
+
+ 0
+ 0
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/confml/sequence_setting_test.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/confml/sequence_setting_test.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,71 @@
+
+
+
+ Feature with a sequence setting (ConfML v2.0)
+
+ A sequence setting
+
+ A folder sub-setting
+
+
+
+
+ A real sub-setting
+
+
+ A file sub-setting
+
+
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+
+
+ seq/default_folder
+ 1.0
+ seq/default_file.txt
+ 1
+ template
+ false
+ 0
+
+
+ seq/def1_folder
+ 1.25
+ seq/def1_file.txt
+ 128
+ def1
+ false
+ 1
+
+
+ seq/def2_folder
+ 1.5
+ seq/def2_file.txt
+ 256
+ def2
+ false
+ 1
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/implml/multiselection.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/implml/multiselection.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+ Selected options: {% for value in feat_tree.MultiSelectionTest.MultiSelectionSetting._value or [] -%}"{{ value }}", {% endfor %}
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/implml/name_id_mapping_test.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/implml/name_id_mapping_test.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+
+
+Selection: {{ feat_tree.NameIdMappingTestTargetSettings.Selection._value }}
+Int: {{ feat_tree.NameIdMappingTestTargetSettings.Int._value }}
+Real: {{ feat_tree.NameIdMappingTestTargetSettings.Real._value }}
+Sequence.Selection: {% for value in feat_tree.NameIdMappingTestTargetSettings.Sequence.Selection._value -%}"{{ value }}", {% endfor %}
+Sequence.Int: {% for value in feat_tree.NameIdMappingTestTargetSettings.Sequence.Int._value -%}"{{ value }}", {% endfor %}
+Sequence.Real: {% for value in feat_tree.NameIdMappingTestTargetSettings.Sequence.Real._value -%}"{{ value }}", {% endfor %}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/base/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/confml/custom.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/confml/custom.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+ Settings for configuring the base layer's settings via rules and other implementation files on this layer
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/confml/view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/confml/view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+
+
+
+ Testing view located on layer 1.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/content/apps/app1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/content/apps/app1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/content/apps/app2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/content/apps/app2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/content/invocation_phase_test_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/content/invocation_phase_test_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/content/invocation_phase_test_2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/content/invocation_phase_test_2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 2
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/implml/conditional_container.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/conditional_container.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+TempFeature.String: {{ feat_tree.TempFeature.String._value }}
+
+
+
+
+
+
+
+
+
+
+TempFeature.String: {{ feat_tree.TempFeature.String._value }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/implml/invocation_phase_test.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/invocation_phase_test.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/implml/missing_file_in_report_test.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/missing_file_in_report_test.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ feat_tree.TempFeatureMissingFile.Test1._value }}
+
+
+ {{ feat_tree.TempFeatureMissingFile.Test2._value }}
+
+
+
+
+
+
+
+
+ True configures TempFeatureMissingFile.Test1 = {% delete_file('output/content/missing_output_file_test1.txt') %}
+ True configures TempFeatureMissingFile.Test2 = {% delete_file('output/content/missing_output_file_test2.txt') %}
+
+
+def delete_file(file):
+ import os
+ print "removing %s" % file
+ os.remove(file)
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/implml/output_override_test.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/output_override_test.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True configures TempFeature2.FilesToCopy = {% get_file_seq() %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+def get_file_seq():
+ # Just return some files present on the custom/ layer
+ return [['invocation_phase_test_1.txt'],
+ ['invocation_phase_test_2.txt'],
+ ['overlay/overlay_folder/overlay.txt']]
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/implml/simple_tempvars.implml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/simple_tempvars.implml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+ True configures TempFeature.String = TempFeature.String + " and more testing"
+ True configures TempFeature.Int = TempFeature.Int + 1
+ True configures TempFeature.Real = TempFeature.Real + 0.25
+
+
+
+
+
+
+TempFeature.String: {{ feat_tree.TempFeature.String._value }}
+TempFeature.Int: {{ feat_tree.TempFeature.Int._value }}
+TempFeature.Real: {{ feat_tree.TempFeature.Real._value }}
+TempFeature.Boolean: {{ feat_tree.TempFeature.Boolean._value }}
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/custom/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/data/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/data/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,84 @@
+
+
+
+
+ 555
+ カタカナ <&>
+
+
+
+
+ seq/default_folder
+ 10.10
+ seq/default_file.txt
+ 120
+ <&カタカナ>
+ true
+ 2
+
+
+
+
+
+ 1.5
+ 256
+ test
+ true
+ 1
+
+
+
+
+
+ Entry 4 (new)
+
+
+ Entry 5 (new)
+
+
+
+ Entry 4 (new)
+ 140
+
+
+ Entry 5 (new)
+ 150
+
+
+
+ Entry 4 (new)
+ 1.4
+
+
+ Entry 5 (new)
+ 1.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "opt 2" "opt 4" "opt 5"
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/data/content/file1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/data/content/file1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/data/content/file2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/data/content/file2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test2
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/data/content/file3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/data/content/file3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test3
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/data/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/data/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/generation_test_project/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+from testautomation import testcli
+
+if __name__ == '__main__':
+ testcli.run(__init__.collect_suite())
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/scripttest_common.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/scripttest_common.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+if sys.platform == "win32":
+ CONE_SCRIPT = "cone.cmd"
+else:
+ CONE_SCRIPT = "cone.sh"
+
+def get_cmd(action):
+ """Return the command used to run the ConE sub-action"""
+ if 'CONE_PATH' in os.environ:
+ CONE_CMD = os.path.join(os.environ['CONE_PATH'], CONE_SCRIPT)
+ if not os.path.exists(CONE_CMD):
+ raise RuntimeError("'%s' does not exist!" % CONE_CMD)
+ return '"%s" %s' % (CONE_CMD, action)
+ else:
+ return 'python "%s" %s' % (os.path.normpath(os.path.join(ROOT_PATH,'../cone_tool.py')), action)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/content/test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/content/test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/none.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/none.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1_t2.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1_t2.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1_t2_t3.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1_t2_t3.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1_t3.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t1_t3.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t2.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t2.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t2_t3.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t2_t3.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t3.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/implml/t3.content Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/layer/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/layer/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/tag_filtering_test_project/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/tag_filtering_test_project/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/template.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/template.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+{% for feat in rep_data.ref_noimpl %}{{ feat.ref }}
+{% endfor %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/test_project.cpf
Binary file configurationengine/source/scripts/tests/test_project.cpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/test_template/template2.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/test_template/template2.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+{% for feat in rep_data.ref_noimpl %}{{ feat.ref }}
+{% endfor %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/test_variant.cpf
Binary file configurationengine/source/scripts/tests/test_variant.cpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/api_template.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/api_template.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+{% set columns = {'fqr':'Full reference',
+ 'name':'Name',
+ 'type':'Type',
+ 'desc':'Description',
+ } -%}
+
+Changed features:
+{% for item in columns|sort -%}{{ columns[item] }}|{%- endfor -%}
+{%- for item in columns|sort -%}{{ columns[item] }}|{%- endfor %}
+
+{% for fqr in data.sourcedata.features|sort -%}
+ {%- if fqr in data.targetdata.features and not data.sourcedata.features[fqr]._compare(data.targetdata.features[fqr], columns.keys()) -%}
+ {%- for colname in columns -%}
+ {{- data.sourcedata.features[fqr][colname] }}|
+ {%- endfor -%}
+ {%- for colname in columns -%}
+ {{- data.targetdata.features[fqr][colname] }}|
+ {%- endfor %}
+{% endif -%}
+{%- endfor %}
+
+Only in sourcedata:
+{% for fqr in data.sourcedata.features|sort -%}
+ {%- if fqr not in data.targetdata.features -%}
+ {%- for colname in columns -%}
+ {{ data.sourcedata.features[fqr][colname] }}|
+ {%- endfor %}
+{% endif -%}
+{%- endfor %}
+
+Only in targetdata:
+{% for fqr in data.targetdata.features|sort -%}
+ {%- if fqr not in data.sourcedata.features -%}
+ {%- for colname in columns -%}
+ {{ data.targetdata.features[fqr][colname] }}|
+ {%- endfor %}
+{% endif -%}
+{%- endfor %}
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/data_template.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/data_template.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+Changed values:
+{% for fqr in data.sourcedata.features|sort -%}
+{%- if fqr in data.targetdata.features and data.sourcedata.features[fqr]['value'] != data.targetdata.features[fqr]['value'] -%}
+{{ data.sourcedata.features[fqr]['fqr'] }} | {{ data.sourcedata.features[fqr]['value'] }} | {{ data.targetdata.features[fqr]['value'] }}
+{% endif -%}
+{%- endfor -%}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/expected/api_p1r1_vs_p1r1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/expected/api_p1r1_vs_p1r1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+Changed features:
+Description|Full reference|Name|Type|Description|Full reference|Name|Type|
+
+
+
+Only in sourcedata:
+
+
+Only in targetdata:
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/expected/api_p1r1_vs_p1r4.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/expected/api_p1r1_vs_p1r4.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,17 @@
+Changed features:
+Description|Full reference|Name|Type|Description|Full reference|Name|Type|
+
+
+
+Only in sourcedata:
+
+
+Only in targetdata:
+Layer4Feature|None|Layer 4 Feature|Feature with some setting types|
+Layer4Feature.BooleanSetting|boolean|Boolean setting|A boolean setting|
+Layer4Feature.IntSetting|int|Int setting|An int setting|
+Layer4Feature.RealSetting|real|Real setting|A real setting|
+Layer4Feature.SelectionSetting|selection|Selection setting|A selection setting|
+Layer4Feature.SequenceSetting|sequence|Sequence setting|A sequence setting|
+Layer4Feature.SequenceSetting.StringSubSetting|string|String sub-setting|A string sub-setting|
+Layer4Feature.StringSetting|string|String setting|A string setting|
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/expected/api_p1r1_vs_p2r1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/expected/api_p1r1_vs_p2r1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+Changed features:
+Description|Full reference|Name|Type|Description|Full reference|Name|Type|
+
+BasicSettingTypesTest.IntSetting|int|Int setting|An int setting|BasicSettingTypesTest.IntSetting|int|Int setting|An int setting (description changed)|
+BasicSettingTypesTest.RealSetting|real|Real setting|A real setting|BasicSettingTypesTest.RealSetting|real|Real setting (name changed)|A real setting|
+
+
+Only in sourcedata:
+BasicSettingTypesTest.BooleanSetting|boolean|Boolean setting|A boolean setting|
+
+
+Only in targetdata:
+BasicSettingTypesTest.BooleanSettingRefChanged|boolean|Boolean setting|A boolean setting|
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p1r1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p1r1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Changed values:
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p1r4.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p1r4.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+Changed values:
+BasicSettingTypesTest.BooleanSetting | True | False
+BasicSettingTypesTest.IntSetting | 10 | 444
+BasicSettingTypesTest.RealSetting | 3.14 | 3.14567
+BasicSettingTypesTest.SelectionSetting | 1 | 4
+BasicSettingTypesTest.StringSetting | default string | layer 4 string
+Feature2.SequenceSetting | [['1', 'default 1'], ['2', 'default 2']] | [['444', 'layer4 (1)'], ['444', 'layer4 (2)']]
+Feature2.SequenceSetting.IntSubSetting | ['1', '2'] | ['444', '444']
+Feature2.SequenceSetting.StringSubSetting | ['default 1', 'default 2'] | ['layer4 (1)', 'layer4 (2)']
+FileFolderTest.FileSetting.localPath | default_file.txt | layer2_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p2r1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p2r1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+Changed values:
+BasicSettingTypesTest.StringSetting | default string | value changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/project1.zip
Binary file configurationengine/source/scripts/tests/testdata/compare/project1.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/compare/project2.zip
Binary file configurationengine/source/scripts/tests/testdata/compare/project2.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/content/invocation_phase_test_common_ns.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/content/invocation_phase_test_common_ns.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 2
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/content/invocation_phase_test_contentml_ns.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/content/invocation_phase_test_contentml_ns.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 2
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/content/simple_tempvars_test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/content/simple_tempvars_test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+TempFeature.String: testing and more testing
+TempFeature.Int: 501
+TempFeature.Real: 1.75
+TempFeature.Boolean: True
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/content/temp_seq_test/invocation_phase_test_1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/content/temp_seq_test/invocation_phase_test_1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/content/temp_seq_test/invocation_phase_test_2.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/content/temp_seq_test/invocation_phase_test_2.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 2
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/content/template_string_condition_true.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/content/template_string_condition_true.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,3 @@
+
+TempFeature.String: testing
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/multiselection.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/multiselection.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+Selected options: "opt 2", "opt 4", "opt 5",
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/name_id_mapping_test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/name_id_mapping_test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+Selection: Entry 4 (new)
+Int: 140
+Real: 1.4
+Sequence.Selection: "Entry 2", "Entry 4 (new)", "Entry 5 (new)",
+Sequence.Int: "120", "140", "150",
+Sequence.Real: "1.2", "1.4", "1.5",
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/sis/app1.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/sis/app1.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected/test_subdir/output_subdir_test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/test_subdir/output_subdir_test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/expected_report.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected_report.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1698 @@
+
+
+
+ ConE generation report
+
+
+
+
+ Generation summary:
+
+
+ Statistics
+
+
+ Refs in files
+ 12
+
+
+ Refs with no implementation
+ 13
+
+
+ Details
+
+
+ Report generated
+ 30.09.2009 15:42:50
+
+
+ Generation duration
+ 0.547
+
+
+ Generation log
+ cone.log
+
+
+ Generation options
+
+
+ Layers
+ [-1]
+
+
+ Added
+ None
+
+
+ Dryrun
+ False
+
+
+ Verbose
+ 3
+
+
+ Overrides
+ None
+
+
+ Project
+ this_is_ignored\generation_test_project
+
+
+ Report
+ report.html
+
+
+ Impls
+ None
+
+
+ Output
+ output
+
+
+ Configuration
+ root.confml
+
+
+ Working directory
+ this_is_ignored\source\scripts\tests\temp\gen_ll3
+
+
+
+ Rule execution results:
+
+
+
+
+ Output files:
+
+
+
+ Refs with no implementation:
+
+
+
+ API
+ Data
+
+
+
+
+ BasicSettingTypesTest.IntSetting
+ Name: Int setting
+ Type: int
+ ConfML: base\confml\basic_setting_types_test.confml
+
+
+
+
+
+
+
+
+
+ BasicSettingTypesTest.StringSetting
+ Name: String setting
+ Type: string
+ ConfML: base\confml\basic_setting_types_test.confml
+
+
+
+
+
+
+
+
+
+ Condition.Boolean
+ Name: Boolean
+ Type: boolean
+ ConfML: autodata.confml
+
+
+
+
+
+
+
+
+
+ Condition.Int
+ Name: Int
+ Type: int
+ ConfML: autodata.confml
+
+
+
+
+
+
+
+
+
+ Condition.Real
+ Name: Real
+ Type: real
+ ConfML: autodata.confml
+
+
+
+
+
+
+
+
+
+ Condition.String
+ Name: String
+ Type: string
+ ConfML: autodata.confml
+
+
+
+
+
+
+
+
+
+ Condition.Unused
+ Name: Unused
+ Type: boolean
+ ConfML: autodata.confml
+
+
+
+
+
+
+
+
+
+ Feature1.SequenceSetting
+ Name: Sequence setting
+ Type: sequence
+ ConfML: base\confml\feature1.confml
+
+
+
+
+
+
+
+
+
+
+
+
+ Real sub-setting
+
+
+ 1.25
+
+ 1.5
+
+ 1.5
+
+
+
+
+
+
+
+ Int sub-setting
+
+
+ 128
+
+ 256
+
+ 256
+
+
+
+
+
+
+
+ String sub-setting
+
+
+ def1
+
+ def2
+
+ test
+
+
+
+
+
+
+
+ Boolean sub-setting
+
+
+ false
+
+ false
+
+ true
+
+
+
+
+
+
+
+ Selection sub-setting
+
+
+ 1
+
+ 1
+
+ 1
+
+
+
+
+
+
+
+
+
+
+ NameIdMappingTestSourceSequences.StringSequence
+ Name: String sequence
+ Type: sequence
+ ConfML: base\confml\name_id_mapping_test.confml
+
+
+
+
+
+
+
+
+
+
+
+
+ Value sub-setting
+
+
+ Entry 1
+
+ Entry 2
+
+ Entry 3
+
+ Entry 4 (new)
+
+ Entry 5 (new)
+
+
+
+
+
+
+
+
+
+
+ NameIdMappingTestSourceSequences.StringToIntSequence
+ Name: String-to-int sequence
+ Type: sequence
+ ConfML: base\confml\name_id_mapping_test.confml
+
+
+
+
+
+
+
+
+
+
+
+
+ Name sub-setting
+
+
+ Entry 1
+
+ Entry 2
+
+ Entry 3
+
+ Entry 4 (new)
+
+ Entry 5 (new)
+
+
+
+
+
+
+
+ Value sub-setting
+
+
+ 100
+
+ 120
+
+ 130
+
+ 140
+
+ 150
+
+
+
+
+
+
+
+
+
+
+ NameIdMappingTestSourceSequences.StringToRealSequence
+ Name: String-to-real sequence
+ Type: sequence
+ ConfML: base\confml\name_id_mapping_test.confml
+
+
+
+
+
+
+
+
+
+
+
+
+ Name sub-setting
+
+
+ Entry 1
+
+ Entry 2
+
+ Entry 3
+
+ Entry 4 (new)
+
+ Entry 5 (new)
+
+
+
+
+
+
+
+ Value sub-setting
+
+
+ 1.1
+
+ 1.2
+
+ 1.3
+
+ 1.4
+
+ 1.5
+
+
+
+
+
+
+
+
+
+
+ SequenceSettingTest.SequenceSetting
+ Name: Sequence setting
+ Type: sequence
+ ConfML: base\confml\sequence_setting_test.confml
+
+
+
+
+
+
+
+
+
+
+
+
+ Folder sub-setting
+
+
+ ['seq/default_folder', None]
+
+
+
+
+
+
+
+ localPath
+
+
+ seq/default_folder
+
+
+
+
+
+
+
+ targetPath
+
+
+ None
+
+
+
+
+
+
+
+ Real sub-setting
+
+
+ 10.10
+
+
+
+
+
+
+
+ File sub-setting
+
+
+ ['seq/default_file.txt', None]
+
+
+
+
+
+
+
+ localPath
+
+
+ seq/default_file.txt
+
+
+
+
+
+
+
+ targetPath
+
+
+ None
+
+
+
+
+
+
+
+ Int sub-setting
+
+
+ 120
+
+
+
+
+
+
+
+ String sub-setting
+
+
+ <&カタカナ>
+
+
+
+
+
+
+
+ Boolean sub-setting
+
+
+ true
+
+
+
+
+
+
+
+ Selection sub-setting
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+ TempFeature.Unused
+ Name: Unused
+ Type: boolean
+ ConfML: autodata.confml
+
+
+
+
+
+
+
+
+ Not generated output files:
+
+
+
+ Output file
+
+
+
+
+ output\content\template_string_condition_false.txt
+
+
+
+
+ output\content\missing_output_file_test1.txt
+
+
+
+
+ output\content\missing_output_file_test2.txt
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/generate/test_project_invalid_data_refs.zip
Binary file configurationengine/source/scripts/tests/testdata/generate/test_project_invalid_data_refs.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/custom_value_report_template.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/custom_value_report_template.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,32 @@
+{% extends "cone_base.html" %}
+{% block title %}Data value info{% endblock %}
+{% block content %}
+ Configuration data value info (custom template)
+
+
+
+ Ref
+ Name
+ Type
+ {% for config in data.value_data.configs %}
+ {{ config.path }}
+ {% endfor %}
+
+ {% for feature_group in data.value_data.feature_groups %}
+ {{ feature_group.name }}
+ {% for feature in feature_group.features %}
+ {% if feature.modified %}{% else %} {% endif %}
+ {{ feature.ref }}
+ {{ feature.name }}
+ {{ feature.type }}
+
+ {% for config in data.value_data.configs %}
+ {{ config.values[feature.ref] }}
+ {% endfor %}
+
+
+ {% endfor -%}
+ {% endfor %}
+
+
+{% endblock %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/api_report.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/api_report.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,859 @@
+
+
+
+
+
+API info - ConE
+
+
+
+
+
Configuration API info
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/content_report.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/content_report.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,177 @@
+
+
+
+
+
+Content info - ConE
+
+
+
+
+
Configuration content files
+
+
+
+ Content file
+ Actual files (used one last)
+
+
+
+ default_file.txt
+ Layer1/content/default_file.txt
+
+
+
+ layer2_file.txt
+ Layer2/content/layer2_file.txt
+
+
+
+ override_test.txt
+ Layer1/content/override_test.txt Layer3/content/override_test.txt
+
+
+
+ seq/def1_file.txt
+ Layer1/content/seq/def1_file.txt
+
+
+
+ seq/def2_file.txt
+ Layer1/content/seq/def2_file.txt
+
+
+
+ seq/layer2_file.txt
+ Layer2/content/seq/layer2_file.txt
+
+
+
+ seq/layer2_file2.txt
+ Layer2/content/seq/layer2_file2.txt
+
+
+
+ seq/layer3_file.txt
+ Layer3/content/seq/layer3_file.txt
+
+
+
+ seq/layer4_file.txt
+ Layer4/content/seq/layer4_file.txt
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/impl_report.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/impl_report.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,190 @@
+
+
+
+
+
+Implementation info - ConE
+
+
+
+
+
Implementations
+
+
+
+ File
+ Index
+ Type
+ Phase
+ Tags
+ Refs
+
+
+
+ Layer1/implml/bitmask_test.templateml
+ 0
+ templateml
+ normal
+
+ BitmaskTest.Bit0 BitmaskTest.Bit1 BitmaskTest.Bit2 BitmaskTest.Bit3 BitmaskTest.Bit4 BitmaskTest.Bit5
+
+
+
+ Layer1/implml/feature1_1.templateml
+ 0
+ templateml
+ normal
+
+ Feature1.IntSetting
+
+
+
+ Layer1/implml/feature1_2.templateml
+ 0
+ templateml
+ normal
+
+ Feature1.StringSetting
+
+
+
+ Layer1/implml/feature1_sequence.templateml
+ 0
+ templateml
+ normal
+
+ Feature1.SequenceSetting
+
+
+
+ Layer1/implml/feature2.templateml
+ 0
+ templateml
+ normal
+
+ Feature2.SequenceSetting
+
+
+
+ Layer1/implml/time_types_test.templateml
+ 0
+ templateml
+ normal
+
+ TimeTypesTest.DateSetting TimeTypesTest.TimeSetting TimeTypesTest.DateTimeSetting TimeTypesTest.DurationSetting
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/impl_report_with_containers.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/impl_report_with_containers.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,307 @@
+
+
+
+
+
+Implementation info - ConE
+
+
+
+
+
Implementations
+
+
+
+ File
+ Index
+ Type
+ Phase
+ Tags
+ Refs
+
+
+
+ base/implml/multiselection.templateml
+ 0
+ templateml
+ normal
+
+ MultiSelectionTest.MultiSelectionSetting
+
+
+
+ base/implml/name_id_mapping_test.templateml
+ 0
+ templateml
+ normal
+
+ NameIdMappingTestTargetSettings.Selection NameIdMappingTestTargetSettings.Int NameIdMappingTestTargetSettings.Real NameIdMappingTestTargetSettings.Sequence.Selection NameIdMappingTestTargetSettings.Sequence.Int NameIdMappingTestTargetSettings.Sequence.Real
+
+
+
+ custom/implml/conditional_container.implml
+ 0
+ templateml
+ normal
+
+ TempFeature.String
+
+
+
+ custom/implml/conditional_container.implml
+ 1
+ templateml
+ normal
+
+ TempFeature.String
+
+
+
+ custom/implml/conditional_container.implml
+ 2
+ content
+ normal
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/conditional_container.implml
+ 3
+ content
+ normal
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/invocation_phase_test.implml
+ 0
+ content
+ normal
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/invocation_phase_test.implml
+ 1
+ content
+ post
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/invocation_phase_test.implml
+ 2
+ content
+ normal
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/invocation_phase_test.implml
+ 3
+ content
+ post
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/missing_file_in_report_test.implml
+ 0
+ templateml
+ normal
+
+ TempFeatureMissingFile.Test1 TempFeatureMissingFile.Test2
+
+
+
+ custom/implml/missing_file_in_report_test.implml
+ 1
+ ruleml
+ post
+
+ None
+
+
+
+ custom/implml/output_override_test.implml
+ 0
+ content
+ normal
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/output_override_test.implml
+ 1
+ content
+ normal
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/output_override_test.implml
+ 2
+ content
+ normal
+ target = ['rofs3']
+ None
+
+
+
+ custom/implml/seq_tempvar.implml
+ 0
+ ruleml
+ pre
+
+ None
+
+
+
+ custom/implml/seq_tempvar.implml
+ 1
+ content
+ normal
+ target = ['rofs3']
+ TempFeature2.FilesToCopy.FilePath
+
+
+
+ custom/implml/simple_tempvars.implml
+ 0
+ ruleml
+ pre
+
+ None
+
+
+
+ custom/implml/simple_tempvars.implml
+ 1
+ templateml
+ normal
+
+ TempFeature.String TempFeature.Int TempFeature.Real TempFeature.Boolean
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/value_report.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,27 @@
+Name,Type,Possible values,product_langpack_01_root.confml,product_langpack_02_root.confml,product_langpack_03_root.confml,
+
+All settings
+Real setting,real,"",3.14,3.14,3.14,
+Int setting,int,"",10,10,10,
+String setting,string,"",string from product (langpack 01) config,string from product (langpack 02) config,string from product (langpack 03) config,
+Boolean setting,boolean,"",True,True,True,
+Selection setting,selection,"Option0
+Option1
+Option2
+Option3
+Option4
+",Option1,Option1,Option1,
+Sequence setting,sequence,"",,,,
+Sequence setting,sequence,"",,,,
+Real setting,real,"",10.5,10.5,10.5,
+Int setting,int,"",1001,1002,1003,
+String setting,string,"",langpack 01 string,langpack 02 string,langpack 03 string,
+Boolean setting,boolean,"",True,True,True,
+Selection setting,selection,"Option0
+Option1
+Option2
+Option3
+Option4
+",Option1,Option1,Option1,
+Sequence setting,sequence,"",,,,
+Sequence setting,sequence,"",,,,
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/value_report_custom.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_custom.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,292 @@
+
+
+
+
+
+Data value info - ConE
+
+
+
+
+
Configuration data value info (custom template)
+
+
+
+ Ref
+ Name
+ Type
+
+ product_root.confml
+
+
+
+ All settings
+
+
+ Asset1Feature1.RealSetting
+ Real setting
+ real
+
+
+ 3.14
+
+
+
+
+
+ Asset1Feature1.IntSetting
+ Int setting
+ int
+
+
+ 10
+
+
+
+
+
+ Asset1Feature1.StringSetting
+ String setting
+ string
+
+
+ string from product config
+
+
+
+
+
+ Asset1Feature1.BooleanSetting
+ Boolean setting
+ boolean
+
+
+ True
+
+
+
+
+
+ Asset1Feature1.SelectionSetting
+ Selection setting
+ selection
+
+
+ Option1
+
+
+
+
+
+ Asset1Feature1.SequenceSetting
+ Sequence setting
+ sequence
+
+
+ SequenceData(columns=[SequenceColumn(ref='RealSubSetting', name='Real sub-setting', type='real'), SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string'), SequenceColumn(ref='BooleanSubSetting', name='Boolean sub-setting', type='boolean'), SequenceColumn(ref='SelectionSubSetting', name='Selection sub-setting', type='selection')], rows=[{'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'test (product)', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.25', 'IntSubSetting': '128', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def1', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def2', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'test', 'BooleanSubSetting': 'true'}])
+
+
+
+
+
+ Asset1Feature2.SequenceSetting
+ Sequence setting
+ sequence
+
+
+ SequenceData(columns=[SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string')], rows=[{'IntSubSetting': '1', 'StringSubSetting': 'default 1'}, {'IntSubSetting': '2', 'StringSubSetting': 'default 2'}])
+
+
+
+
+
+ Asset2Feature1.RealSetting
+ Real setting
+ real
+
+
+ 10.5
+
+
+
+
+
+ Asset2Feature1.IntSetting
+ Int setting
+ int
+
+
+ 1200
+
+
+
+
+
+ Asset2Feature1.StringSetting
+ String setting
+ string
+
+
+ default string
+
+
+
+
+
+ Asset2Feature1.BooleanSetting
+ Boolean setting
+ boolean
+
+
+ True
+
+
+
+
+
+ Asset2Feature1.SelectionSetting
+ Selection setting
+ selection
+
+
+ Option1
+
+
+
+
+
+ Asset2Feature1.SequenceSetting
+ Sequence setting
+ sequence
+
+
+ SequenceData(columns=[SequenceColumn(ref='RealSubSetting', name='Real sub-setting', type='real'), SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string'), SequenceColumn(ref='BooleanSubSetting', name='Boolean sub-setting', type='boolean'), SequenceColumn(ref='SelectionSubSetting', name='Selection sub-setting', type='selection')], rows=[{'RealSubSetting': '1.25', 'IntSubSetting': '128', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def1', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def2', 'BooleanSubSetting': 'false'}])
+
+
+
+
+
+ Asset2Feature2.SequenceSetting
+ Sequence setting
+ sequence
+
+
+ SequenceData(columns=[SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string')], rows=[{'IntSubSetting': '1', 'StringSubSetting': 'default 1'}, {'IntSubSetting': '2', 'StringSubSetting': 'default 2'}])
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/value_report_langpacks.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_langpacks.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,773 @@
+
+
+
+
+
+Data value info - ConE
+
+
+
+
+
Configuration data value info
+
+
+
+ Name
+ Type
+ Possible values
+
+ product_langpack_01_root.confml
+
+ product_langpack_02_root.confml
+
+ product_langpack_03_root.confml
+
+
+
+ All settings
+
+
+ Real setting
+ real
+
+
+
+ 3.14
+
+ 3.14
+
+ 3.14
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 10
+
+ 10
+
+ 10
+
+
+
+
+
+ String setting
+ string
+
+
+
+ string from product (langpack 01) config
+
+ string from product (langpack 02) config
+
+ string from product (langpack 03) config
+
+
+
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+ True
+
+ True
+
+
+
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+ Option1
+
+ Option1
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Real sub-setting
+ 10001.5
+
+ Int sub-setting
+ 10001
+
+ String sub-setting
+ test (product, lang 01)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 5
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 10002.5
+
+ Int sub-setting
+ 10002
+
+ String sub-setting
+ test (product, lang 02)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 5
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 10003.5
+
+ Int sub-setting
+ 10003
+
+ String sub-setting
+ test (product, lang 03)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 5
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+
+
+
+ Real setting
+ real
+
+
+
+ 10.5
+
+ 10.5
+
+ 10.5
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 1001
+
+ 1002
+
+ 1003
+
+
+
+
+
+ String setting
+ string
+
+
+
+ langpack 01 string
+
+ langpack 02 string
+
+ langpack 03 string
+
+
+
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+ True
+
+ True
+
+
+
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+ Option1
+
+ Option1
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/value_report_multi_mixed.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_multi_mixed.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,925 @@
+
+
+
+
+
+Data value info - ConE
+
+
+
+
+
Configuration data value info
+
+
+
+ Name
+ Type
+ Possible values
+
+ product_root.confml
+
+ product_langpack_01_root.confml
+
+ product_langpack_02_root.confml
+
+ product_langpack_03_root.confml
+
+
+
+ All settings
+
+
+ Real setting
+ real
+
+
+
+ 3.14
+
+ 3.14
+
+ 3.14
+
+ 3.14
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 10
+
+ 10
+
+ 10
+
+ 10
+
+
+
+
+
+ String setting
+ string
+
+
+
+ string from product config
+
+ string from product (langpack 01) config
+
+ string from product (langpack 02) config
+
+ string from product (langpack 03) config
+
+
+
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+ True
+
+ True
+
+ True
+
+
+
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+ Option1
+
+ Option1
+
+ Option1
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 10001.5
+
+ Int sub-setting
+ 10001
+
+ String sub-setting
+ test (product, lang 01)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 5
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 10002.5
+
+ Int sub-setting
+ 10002
+
+ String sub-setting
+ test (product, lang 02)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 5
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 10003.5
+
+ Int sub-setting
+ 10003
+
+ String sub-setting
+ test (product, lang 03)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 5
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+
+
+
+ Real setting
+ real
+
+
+
+ 10.5
+
+ 10.5
+
+ 10.5
+
+ 10.5
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 1200
+
+ 1001
+
+ 1002
+
+ 1003
+
+
+
+
+
+ String setting
+ string
+
+
+
+ default string
+
+ langpack 01 string
+
+ langpack 02 string
+
+ langpack 03 string
+
+
+
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+ True
+
+ True
+
+ True
+
+
+
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+ Option1
+
+ Option1
+
+ Option1
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/value_report_single.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_single.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,424 @@
+
+
+
+
+
+Data value info - ConE
+
+
+
+
+
Configuration data value info
+
+
+
+ Name
+ Type
+ Possible values
+
+ product_root.confml
+
+
+
+ All settings
+
+
+ Real setting
+ real
+
+
+
+ 3.14
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 10
+
+
+
+
+
+ String setting
+ string
+
+
+
+ string from product config
+
+
+
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+
+
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test (product)
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 3
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 4
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ test
+
+ Boolean sub-setting
+ true
+
+ Selection sub-setting
+ Op1
+
+
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+
+
+
+ Real setting
+ real
+
+
+
+ 10.5
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 1200
+
+
+
+
+
+ String setting
+ string
+
+
+
+ default string
+
+
+
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+
+
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Real sub-setting
+ 1.25
+
+ Int sub-setting
+ 128
+
+ String sub-setting
+ def1
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+ Item 2
+ Real sub-setting
+ 1.5
+
+ Int sub-setting
+ 256
+
+ String sub-setting
+ def2
+
+ Boolean sub-setting
+ false
+
+ Selection sub-setting
+ Op1
+
+
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/value_report_single_with_view.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_single_with_view.html Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,280 @@
+
+
+
+
+
+Data value info - ConE
+
+
+
+
+
Configuration data value info
+
+
+
+ Name
+ Type
+ Possible values
+
+ product_root.confml
+
+
+
+ Asset 1 settings
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+
+
+
+ Asset 1 settings -- Sub-group 1
+
+
+ Real setting
+ real
+
+
+
+ 3.14
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 10
+
+
+
+
+ Asset 1 settings -- Sub-group 2
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+
+
+
+
+ String setting
+ string
+
+
+
+ string from product config
+
+
+
+
+ Asset 2 settings -- Sub-group 1
+
+
+ Real setting
+ real
+
+
+
+ 10.5
+
+
+
+
+
+ Int setting
+ int
+
+
+
+ 1200
+
+
+
+
+ Asset 2 settings -- Sub-group 2
+
+
+ Selection setting
+ selection
+ Option0
+ Option1
+ Option2
+ Option3
+ Option4
+
+
+
+ Option1
+
+
+
+
+
+ Boolean setting
+ boolean
+
+
+
+ True
+
+
+
+
+
+ Sequence setting
+ sequence
+
+
+
+
+ Item 1
+ Int sub-setting
+ 1
+
+ String sub-setting
+ default 1
+ Item 2
+ Int sub-setting
+ 2
+
+ String sub-setting
+ default 2
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/expected/value_report_special_chars.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_special_chars.csv Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+Name,Type,Possible values,csv_test_root.confml,
+
+All settings
+Real setting,real,"",3.14,
+Int setting,int,"",1234,
+String setting,string,"","test, ""test"",
+more test",
+Boolean setting,boolean,"",True,
+Selection setting,selection,"Option0
+Option1
+Option2
+Option3
+Option4
+",Option1,
+Sequence setting,sequence,"",,
+Sequence setting,sequence,"",,
+Real setting,real,"",10.5,
+Int setting,int,"",1234,
+String setting,string,"",カタカナ ÑƒÐ´Ð°Ñ€ÐµÐ½Ð¸Ñ ÎµÎ»Î»Î·Î½Î¹ÎºÎ¬,
+Boolean setting,boolean,"",True,
+Selection setting,selection,"Option0
+Option1
+Option2
+Option3
+Option4
+",Option1,
+Sequence setting,sequence,"",,
+Sequence setting,sequence,"",,
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/include_test_view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/include_test_view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/test_view.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/test_view.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/asset1_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/asset1_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/asset2_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/asset2_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset1/confml/asset1_feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset1/confml/asset1_feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset1/confml/asset1_feature2.confml
Binary file configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset1/confml/asset1_feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset1/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset1/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset2/confml/asset2_feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset2/confml/asset2_feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset2/confml/asset2_feature2.confml
Binary file configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset2/confml/asset2_feature2.confml has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset2/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/assets/asset2/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,15 @@
+
+
+
+
+ test, "test",
+more test
+ 1234
+
+
+
+ カタカナ ÑƒÐ´Ð°Ñ€ÐµÐ½Ð¸Ñ ÎµÎ»Î»Î·Î½Î¹ÎºÎ¬
+ 1234
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/family/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/family/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+ string from family config
+
+
+ 1.5
+ 256
+ test
+ true
+ 1
+
+
+
+
+ 1000
+ 10.5
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/family/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/family/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/family_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/family_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,20 @@
+
+
+
+
+ string from product config
+
+
+ 1.5
+ 256
+ test (product)
+ false
+ 1
+
+
+
+
+ 1200
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_01/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_01/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+ string from product (langpack 01) config
+
+
+ 10001.5
+ 10001
+ test (product, lang 01)
+ false
+ 1
+
+
+
+
+ 1001
+ langpack 01 string
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_01/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_01/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_02/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_02/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+ string from product (langpack 02) config
+
+
+ 10002.5
+ 10002
+ test (product, lang 02)
+ false
+ 1
+
+
+
+
+ 1002
+ langpack 02 string
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_02/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_02/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_03/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_03/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+
+
+
+
+ string from product (langpack 03) config
+
+
+ 10003.5
+ 10003
+ test (product, lang 03)
+ false
+ 1
+
+
+
+
+ 1003
+ langpack 03 string
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_03/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_03/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_01_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_01_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_02_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_02_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_03_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_03_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/product_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/variant/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/variant/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,13 @@
+
+
+
+
+ string from variant config
+ 1234
+
+
+
+ 1234
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/variant/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/variant/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/info/value_report_project/variant_root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/variant_root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/log_config.ini
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/log_config.ini Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,28 @@
+[DEFAULT]
+
+[loggers]
+keys=root,cone
+
+[handlers]
+keys=consoleHandler
+
+[formatters]
+keys=consoleFormatter
+
+[logger_root]
+level=NOTSET
+handlers=consoleHandler
+
+[logger_cone]
+level=NOTSET
+qualname=cone
+handlers=
+
+[handler_consoleHandler]
+class=StreamHandler
+formatter=consoleFormatter
+args=(sys.stdout,)
+level=DEBUG
+
+[formatter_consoleFormatter]
+format=Level:%(levelname)s, Logger:%(name)s, Message:%(message)s
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/assetmerge/data.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/assetmerge/data.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/assetmerge/expected.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/assetmerge/expected.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/last_layer_expected.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_expected.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/last_layer_rename_expected.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_rename_expected.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_expected.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_expected.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_v2_expected.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_v2_expected.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v2_expected.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v2_expected.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/multiple_last_layers_expected.zip
Binary file configurationengine/source/scripts/tests/testdata/merge/multiple_last_layers_expected.zip has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/test_variant_v1.cpf
Binary file configurationengine/source/scripts/tests/testdata/merge/test_variant_v1.cpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/merge/test_variant_v2.cpf
Binary file configurationengine/source/scripts/tests/testdata/merge/test_variant_v2.cpf has changed
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/expected/both.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/expected/both.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,25 @@
+Refs with implementations
+=========================
+
+Ref: Feature1.BooleanSetting
+Impls:
+File = "base\implml\booleansetting_rofs3.templateml", type = "templateml", gen_runs = ['rofs3']
+File = "base\implml\booleansetting_uda.templateml", type = "templateml", gen_runs = ['uda']
+-------------------------------------------------
+Ref: Feature1.IntSetting
+Impls:
+File = "base\implml\intsetting_rofs3.templateml", type = "templateml", gen_runs = ['rofs3']
+-------------------------------------------------
+Ref: Feature1.RealSetting
+Impls:
+File = "base\implml\realsetting_rofs3_uda.templateml", type = "templateml", gen_runs = ['rofs3', 'uda']
+-------------------------------------------------
+Ref: Feature1.StringSetting
+Impls:
+File = "base\implml\stringsetting_uda.templateml", type = "templateml", gen_runs = ['uda']
+
+
+
+Refs with no implementation
+===========================
+Feature1.SelectionSetting
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/expected/rofs3.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/expected/rofs3.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+Refs with implementations
+=========================
+
+Ref: Feature1.BooleanSetting
+Impls:
+File = "base\implml\booleansetting_rofs3.templateml", type = "templateml", gen_runs = []
+-------------------------------------------------
+Ref: Feature1.IntSetting
+Impls:
+File = "base\implml\intsetting_rofs3.templateml", type = "templateml", gen_runs = []
+-------------------------------------------------
+Ref: Feature1.RealSetting
+Impls:
+File = "base\implml\realsetting_rofs3_uda.templateml", type = "templateml", gen_runs = []
+
+
+
+Refs with no implementation
+===========================
+Feature1.SelectionSetting
+Feature1.StringSetting
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/expected/uda.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/expected/uda.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,21 @@
+Refs with implementations
+=========================
+
+Ref: Feature1.BooleanSetting
+Impls:
+File = "base\implml\booleansetting_uda.templateml", type = "templateml", gen_runs = []
+-------------------------------------------------
+Ref: Feature1.RealSetting
+Impls:
+File = "base\implml\realsetting_rofs3_uda.templateml", type = "templateml", gen_runs = []
+-------------------------------------------------
+Ref: Feature1.StringSetting
+Impls:
+File = "base\implml\stringsetting_uda.templateml", type = "templateml", gen_runs = []
+
+
+
+Refs with no implementation
+===========================
+Feature1.IntSetting
+Feature1.SelectionSetting
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/confml/feature1.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/base/confml/feature1.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,89 @@
+
+
+
+ Feature with all supported setting types for ConfML v1.0
+
+ A real setting
+
+
+ An int setting
+
+
+ A string setting
+
+
+ A boolean setting
+
+
+ A selection setting
+
+
+
+
+
+
+
+ A sequence setting
+
+ A real sub-setting
+
+
+ An int sub-setting
+
+
+ A string sub-setting
+
+
+ A boolean sub-setting
+
+
+ A selection sub-setting
+
+
+
+
+
+
+
+
+
+
+ 3.14
+ 10
+ default string
+ true
+ 1
+
+ 1.0
+ 1
+ template
+ false
+ 0
+
+
+ 1.25
+ 128
+ def1
+ false
+ 1
+
+
+ 1.5
+ 256
+ def2
+ false
+ 1
+
+
+
+
+
+
+ true
+ false
+ false
+ true
+ true
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/content/default_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/content/seq/def1_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/content/seq/def2_file.txt
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/implml/booleansetting_rofs3.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/base/implml/booleansetting_rofs3.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+Feature1.BooleanSetting: {{ feat_tree.Feature1.BooleanSetting._value }}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/implml/booleansetting_uda.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/base/implml/booleansetting_uda.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+Feature1.BooleanSetting: {{ feat_tree.Feature1.BooleanSetting._value }}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/implml/intsetting_rofs3.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/base/implml/intsetting_rofs3.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+Feature1.IntSetting: {{ feat_tree.Feature1.IntSetting._value }}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/implml/realsetting_rofs3_uda.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/base/implml/realsetting_rofs3_uda.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+Feature1.RealSetting: {{ feat_tree.Feature1.RealSetting._value }}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/implml/stringsetting_uda.templateml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/base/implml/stringsetting_uda.templateml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,9 @@
+
+
+
+
+
+Feature1.StringSetting: {{ feat_tree.Feature1.StringSetting._value }}
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/base/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/base/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/data/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/data/confml/data.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,12 @@
+
+
+
+
+ 5.555
+ 5555
+ Test test
+ false
+ 2
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/data/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/data/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/project/root.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/project/root.confml Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/testdata/report/template.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/report/template.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,19 @@
+Refs with implementations
+=========================
+{% for feat in rep_data.lines -%}
+{% if not loop.first -%}
+-------------------------------------------------
+{%- endif %}
+Ref: {{ feat.ref }}
+Impls:
+{% for impl in feat.impls -%}
+ File = "{{ impl.name }}", type = "{{ impl.type }}", gen_runs = {{impl.generation_runs}}
+{% endfor -%}
+{% endfor %}
+
+
+Refs with no implementation
+===========================
+{% for feat in rep_data.ref_noimpl -%}
+ {{ feat.ref }}
+{% endfor %}
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_compare.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_compare.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,229 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys
+import os
+import shutil
+import subprocess
+import difflib
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from scripttest_common import get_cmd
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TESTDATA_DIR = os.path.normpath(os.path.join(ROOT_PATH, 'testdata/compare'))
+TEMP_DIR = os.path.normpath(os.path.join(ROOT_PATH, 'temp/compare'))
+
+from cone.public import api
+
+#import conesub_compare
+class TestCompareAction(BaseTestCase):
+
+ def setUp(self):
+ if not os.path.exists(TEMP_DIR):
+ os.makedirs(TEMP_DIR)
+
+ #def test_parse_target_configuration(self):
+ # act = conesub_compare.CompareAction('','','')
+ # self.assertEquals(act.parse_target_configuration("root.confml"), ('','root.confml'))
+ # self.assertEquals(act.parse_target_configuration("x:\foo.cpf;root.confml"), ('x:\foo.cpf','root.confml'))
+ # self.assertEquals(act.parse_target_configuration("root\project;root.confml"), ('root\project','root.confml'))
+ # self.assertEquals(act.parse_target_configuration("http://testserver:8000/external;foo/bar/root.confml"), ('http://testserver:8000/external','foo/bar/root.confml'))
+
+ def test_default_compare(self):
+ # Test comparison using default parameters
+ orig_workdir = os.getcwd()
+ os.chdir(os.path.join(TEMP_DIR))
+ try:
+ project = os.path.join(TESTDATA_DIR, "project1.zip")
+ source_conf = "root1.confml"
+ target_conf = "root2.confml"
+
+ report_file = os.path.join(TEMP_DIR, "data_comparison.html")
+ self.remove_if_exists(report_file)
+
+ command = '%s -p "%s" -s "%s" -t "%s"' \
+ % (get_cmd('compare'), project, source_conf, target_conf)
+ self.run_command(command)
+ self.assert_exists_and_contains_something(report_file)
+ finally:
+ os.chdir(orig_workdir)
+
+ def test_compare_api_same_root(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = None,
+ target_conf = 'root1.confml',
+ template = 'api_template.txt',
+ report_file = 'api_p1r1_vs_p1r1.txt',
+ check_against_expected_output = True)
+
+ def test_compare_data_same_root(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = None,
+ target_conf = 'root1.confml',
+ template = 'data_template.txt',
+ report_file = 'data_p1r1_vs_p1r1.txt',
+ check_against_expected_output = True)
+
+ def test_compare_api_same_project_different_root(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = None,
+ target_conf = 'root4.confml',
+ template = 'api_template.txt',
+ report_file = 'api_p1r1_vs_p1r4.txt',
+ check_against_expected_output = True)
+
+ def test_compare_data_same_project_different_root(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = None,
+ target_conf = 'root4.confml',
+ template = 'data_template.txt',
+ report_file = 'data_p1r1_vs_p1r4.txt',
+ check_against_expected_output = True)
+
+ def test_compare_api_proj1_vs_proj2(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = 'project2.zip',
+ target_conf = 'root1.confml',
+ template = 'api_template.txt',
+ report_file = 'api_p1r1_vs_p2r1.txt',
+ check_against_expected_output = True)
+
+ def test_compare_data_proj1_vs_proj2(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = 'project2.zip',
+ target_conf = 'root1.confml',
+ template = 'data_template.txt',
+ report_file = 'data_p1r1_vs_p2r1.txt',
+ check_against_expected_output = True)
+
+ def test_comparison_using_type_api(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = None,
+ target_conf = 'root4.confml',
+ report_type = 'api',
+ report_file = 'api_p1r1_vs_p1r4.html',
+ check_against_expected_output = False)
+
+ def test_comparison_using_type_data(self):
+ self._run_comparison_test(
+ source_project = 'project1.zip',
+ source_conf = 'root1.confml',
+ target_project = None,
+ target_conf = 'root4.confml',
+ report_type = 'data',
+ report_file = 'data_p1r1_vs_p1r4.html',
+ check_against_expected_output = False)
+
+ def _run_comparison_test(self, **kwargs):
+ """
+ Run comparison test.
+
+ @param source_project: The source project, relative to the test data directory or an
+ absolute path.
+ @param source_conf: The source configuration.
+ @param target_project: The target project, relative to the test data directory
+ If not given or None, the source project will be used also for this.
+ @param target_conf: The target configuration.
+ @param template: The template file used for the report, relative to the test data directory.
+ @param report_type: The report type. Should not be used with the 'template' parameter.
+ @param report_file: The location where the report is written. This will also be used as
+ the name of the expected report file against which the actual report is checked.
+ @param impl_filter: Implementation filter to use.
+ @param check_against_expected_output: If True, the actual report is checked against an
+ expected file with the same name. Otherwise it is just checked that the output
+ file has been created and it contains something.
+ """
+ # Get parameters
+ # ---------------
+ def get_project_absdir(project_dir):
+ if os.path.isabs(project_dir):
+ return project_dir
+ else:
+ return os.path.normpath(os.path.join(TESTDATA_DIR, project_dir))
+
+ source_conf = kwargs['source_conf']
+ target_conf = kwargs['target_conf']
+ source_project = get_project_absdir(kwargs['source_project'])
+ target_project = kwargs.get('target_project', None)
+
+ if target_project != None:
+ target_project = get_project_absdir(target_project)
+ target_conf = target_project + ';' + target_conf
+
+ template = kwargs.get('template', None)
+ report_type = kwargs.get('report_type', None)
+ if template and report_type:
+ raise ValueError("Both 'template' and 'report_type' parameters given")
+ elif not template and not report_type:
+ raise ValueError("Neither 'template' not 'report_type' parameter given")
+ elif template:
+ template = os.path.normpath(os.path.join(TESTDATA_DIR, template))
+
+ report_file = kwargs['report_file']
+ check_against_expected_output = kwargs['check_against_expected_output']
+ actual_report = os.path.normpath(os.path.join(TEMP_DIR, report_file))
+
+ impl_filter = kwargs.get('impl_filter', None)
+
+
+ # Generate output
+ # ----------------
+ if report_type:
+ command = '%s -p "%s" -s "%s" -t "%s" --report-type "%s" --report "%s"' \
+ % (get_cmd('compare'), source_project, source_conf, target_conf, report_type, actual_report)
+ else:
+ command = '%s -p "%s" -s "%s" -t "%s" --template "%s" --report "%s"' \
+ % (get_cmd('compare'), source_project, source_conf, target_conf, template, actual_report)
+
+ if impl_filter:
+ command += ' --impl-filter "%s"' % impl_filter
+
+ self.remove_if_exists(actual_report)
+ self.run_command(command)
+
+
+ # Check output
+ # -------------
+ if check_against_expected_output:
+ expected_report = os.path.normpath(os.path.join(TESTDATA_DIR, 'expected', report_file))
+ self.assert_file_contents_equal(expected_report, actual_report)
+ else:
+ self.assert_exists_and_contains_something(actual_report)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_cone.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_cone.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,102 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys
+import os
+import subprocess
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from scripttest_common import get_cmd
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestConeHelp(BaseTestCase):
+
+ def test_get_help(self):
+ cmd = '%s -h' % get_cmd('')
+ out = self.run_command(cmd)
+ lines = out.split(os.linesep)
+ self.assertTrue('Available actions ' in lines)
+
+ def test_verbose_level(self):
+ cmd = '%s info --print-runtime-info --verbose=5' % get_cmd('')
+ out = self.run_command(cmd)
+ # Check that there are debug messages in the output
+ self.assertTrue('DEBUG : cone' in out)
+ self.assertTrue('sys.path contents:' in out)
+
+ def test_empty_verbose_level(self):
+ cmd = '%s info --print-runtime-info --verbose=' % get_cmd('')
+ out = self.run_command(cmd)
+ self.assertTrue('Python version: ' in out)
+
+ def test_runtime_info_logged(self):
+ # This test makes sure that runtime info is always logged
+ # in the log file
+
+ TEST_DIR = os.path.join(ROOT_PATH, "temp", "log_test")
+ self.recreate_dir(TEST_DIR)
+
+ orig_workdir = os.getcwd()
+ os.chdir(TEST_DIR)
+ try:
+ cmd = '%s' % get_cmd('info')
+ self.run_command(cmd)
+
+ # Check that the default log file has been created
+ self.assertTrue(os.path.exists('cone.log'))
+
+ # Check that it contains the runtime info that should
+ # always be logged
+ f = open('cone.log', 'r')
+ try: data = f.read()
+ finally: f.close()
+ self.assertTrue('DEBUG : cone' in data)
+ self.assertTrue('sys.path contents:' in data)
+ self.assertTrue('PATH:' in data)
+ self.assertTrue('PYTHONPATH:' in data)
+ finally:
+ os.chdir(orig_workdir)
+
+ def test_logfile_in_custom_location(self):
+ TEST_DIR = os.path.join(ROOT_PATH, "temp", "log_test_custom_file")
+ self.recreate_dir(TEST_DIR)
+
+ orig_workdir = os.getcwd()
+ os.chdir(TEST_DIR)
+ try:
+ cmd = '%s --log-file foo/bar.log' % get_cmd('info')
+ self.run_command(cmd)
+
+ self.assertFalse(os.path.exists('cone.log'))
+ self.assertTrue(os.path.exists('foo/bar.log'))
+ finally:
+ os.chdir(orig_workdir)
+
+ def test_custom_log_config(self):
+ CONF_FILE = os.path.join(ROOT_PATH, 'testdata', 'log_config.ini')
+ cmd = '%s --log-config "%s"' % (get_cmd('info'), CONF_FILE)
+ out = self.run_command(cmd)
+ self.assertTrue("Level:DEBUG, Logger:cone, Message:sys.path contents:" in out, out)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_export.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_export.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,416 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys
+import os
+import subprocess
+import zipfile
+import shutil
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation.unzip_file import unzip_file
+from cone.storage.filestorage import FileStorage
+from cone.storage.zipstorage import ZipStorage
+from scripttest_common import get_cmd
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+def abspath(p):
+ return os.path.normpath(os.path.join(ROOT_PATH, p))
+
+TEST_PROJECT_CPF = abspath("test_project.cpf")
+TEMP_DIR = abspath("temp/export")
+EXPORT_TEST_PROJECT = abspath("export_test_project.zip")
+
+class TestExport(BaseTestCase):
+
+ def setUp(self):
+ self.orig_workdir = os.getcwd()
+ os.chdir(ROOT_PATH)
+
+ def tearDown(self):
+ os.chdir(self.orig_workdir)
+
+ def test_get_help(self):
+ cmd = '%s -h' % get_cmd('export')
+ out = self.run_command(cmd)
+ lines = out.split('\r\n')
+ self.assertTrue('Options:' in lines)
+ self.assertTrue(' Export options:' in lines)
+
+ def test_export_project(self):
+ remote = os.path.join(TEMP_DIR, 'test1')
+ self.remove_if_exists(remote)
+
+ self.set_modification_reference_time(TEST_PROJECT_CPF)
+ cmd = '%s -p "%s" -c "root4.confml" -r "%s' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
+ out = self.run_command(cmd)
+ #print out
+ lines = out.split('\r\n')
+ self.assertTrue('Export root4.confml to %s done!' % remote in lines)
+
+ self.assertEquals(set(os.listdir(remote)),
+ set(["Layer1", "Layer2", "Layer3", "Layer4", ".metadata", "root4.confml"]))
+ def fp(p): # fp = full_path
+ return os.path.join(remote, p)
+ self.assert_exists_and_contains_something(fp("Layer1"))
+ self.assert_exists_and_contains_something(fp("Layer2"))
+ self.assert_exists_and_contains_something(fp("Layer3"))
+ self.assert_exists_and_contains_something(fp("Layer4"))
+ self.assert_exists_and_contains_something(fp("root4.confml"))
+
+ self.assert_not_modified(TEST_PROJECT_CPF)
+
+ def test_export_multiple_configurations(self):
+ remote = os.path.join(TEMP_DIR, 'test2')
+ self.remove_if_exists(remote)
+
+ self.set_modification_reference_time(TEST_PROJECT_CPF)
+ cmd = '%s -p "%s" -c "root2.confml" -c "root3.confml" -c "root5.confml" -r "%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
+ out = self.run_command(cmd)
+ #print out
+ lines = out.split('\r\n')
+ self.assertTrue('Export root2.confml to %s done!' % remote in lines)
+ self.assertTrue('Export root3.confml to %s done!' % remote in lines)
+ self.assertTrue('Export root5.confml to %s done!' % remote in lines)
+
+ self.assertEquals(set(os.listdir(remote)),
+ set(["Layer1", "Layer2", "Layer3", "Layer4", "Layer5",
+ ".metadata", "root2.confml", "root3.confml", "root5.confml"]))
+ def fp(p): # fp = full_path
+ return os.path.join(remote, p)
+ self.assert_exists_and_contains_something(fp("Layer1"))
+ self.assert_exists_and_contains_something(fp("Layer2"))
+ self.assert_exists_and_contains_something(fp("Layer3"))
+ self.assert_exists_and_contains_something(fp("Layer4"))
+ self.assert_exists_and_contains_something(fp("Layer5"))
+ self.assert_exists_and_contains_something(fp("root2.confml"))
+ self.assert_exists_and_contains_something(fp("root3.confml"))
+ self.assert_exists_and_contains_something(fp("root5.confml"))
+
+ self.assert_not_modified(TEST_PROJECT_CPF)
+
+ def test_export_multiple_configurations_into_cpf(self):
+ remote = os.path.join(TEMP_DIR, 'test3.cpf')
+ self.remove_if_exists(remote)
+
+ self.set_modification_reference_time(TEST_PROJECT_CPF)
+ cmd = '%s -p "%s" -c "root2.confml" -c "root3.confml" -c "root5.confml" -r "%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
+ out = self.run_command(cmd)
+ #print out
+ lines = out.split('\r\n')
+ self.assertTrue('Export root2.confml to %s done!' % remote in lines)
+ self.assertTrue('Export root3.confml to %s done!' % remote in lines)
+ self.assertTrue('Export root5.confml to %s done!' % remote in lines)
+
+ self.assert_zip_entry_exists(remote, "root2.confml")
+ self.assert_zip_entry_exists(remote, "root3.confml")
+ self.assert_zip_entry_exists(remote, "root5.confml")
+
+ self.assert_not_modified(TEST_PROJECT_CPF)
+
+ def assert_zip_entry_exists(self, zip_file, path):
+ zf = zipfile.ZipFile(zip_file, "r")
+ try:
+ if path not in zf.namelist():
+ self.fail("Entry '%s' not in zip file '%s'." % (path, zipfile))
+ finally:
+ zf.close()
+
+
+ def _run_test_export_project_to_project(self,
+ source_project, source_storage_type,
+ target_project, target_storage_type,
+ empty_folders):
+ # Set up the source project
+ # -------------------------
+ source_path = os.path.join(TEMP_DIR, source_project)
+ self.remove_if_exists(source_path)
+ if source_storage_type == 'file':
+ unzip_file(EXPORT_TEST_PROJECT, source_path, delete_if_exists=True)
+ elif source_storage_type == 'zip':
+ self.create_dir_for_file_path(source_path)
+ shutil.copy2(EXPORT_TEST_PROJECT, source_path)
+ else:
+ raise RuntimeError('Invalid storage type %r' % source_storage_type)
+
+ # Set up the target project
+ # -------------------------
+ target_path = os.path.join(TEMP_DIR, target_project)
+ self.remove_if_exists(target_path)
+ if target_storage_type not in ('file', 'zip'):
+ raise RuntimeError('Invalid storage type %r' % target_storage_type)
+
+ # Run the command
+ # ---------------
+ if empty_folders: empty_folder_switch = ''
+ else: empty_folder_switch = '--exclude-folders'
+ cmd = '%s -p "%s" -c "root5.confml" -r "%s" %s' % \
+ (get_cmd('export'), source_path, target_path, empty_folder_switch)
+ out = self.run_command(cmd)
+
+ # Check the output
+ # ----------------
+ if target_storage_type == 'file': storage_class = FileStorage
+ elif target_storage_type == 'zip': storage_class = ZipStorage
+
+ storage = storage_class(target_path, 'r')
+ res_list = storage.list_resources("/", recurse=True, empty_folders=True)
+
+ expected = ['.metadata',
+ 'root5.confml',
+ 'Layer1/root.confml',
+ 'Layer2/root.confml',
+ 'Layer3/root.confml',
+ 'Layer4/root.confml',
+ 'Layer5/root.confml',]
+ for res in expected:
+ self.assertTrue(res in res_list, "%r not in %r" % (res, res_list))
+ self.assertFalse(storage.is_folder(res), "%r is a folder")
+
+ not_expected = ['Layer1/foo/foo.txt',
+ 'Layer2/foo/layer2_foo.txt',
+ 'Layer3/foo/layer3_foo.txt',
+ 'Layer4/foo/layer4_foo.txt',
+ 'Layer5/foo/layer5_foo.txt',]
+ for res in not_expected:
+ self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
+
+ # Check empty folders
+ expected = ['Layer1/doc/empty',
+ 'Layer1/content/empty',
+ 'Layer1/implml/empty',
+ 'Layer3/doc/empty',
+ 'Layer3/content/empty',
+ 'Layer3/implml/empty',]
+ not_expected = ['Layer1/foo/empty',
+ 'Layer3/foo/empty']
+ if empty_folders:
+ for res in expected:
+ self.assertTrue(res in res_list, "%r not in %r" % (res, res_list))
+ self.assertTrue(storage.is_folder(res), "%r is not a folder")
+
+ for res in not_expected:
+ self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
+ else:
+ for res in expected + not_expected:
+ self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
+
+
+ def test_export_file_to_file(self):
+ self._run_test_export_project_to_project(
+ source_project = 'f2f/source',
+ source_storage_type = 'file',
+ target_project = 'f2f/target',
+ target_storage_type = 'file',
+ empty_folders = False)
+
+ self._run_test_export_project_to_project(
+ source_project = 'f2f/source_ef',
+ source_storage_type = 'file',
+ target_project = 'f2f/target_ef',
+ target_storage_type = 'file',
+ empty_folders = True)
+
+ def test_export_zip_to_zip(self):
+ self._run_test_export_project_to_project(
+ source_project = 'z2z/source.zip',
+ source_storage_type = 'zip',
+ target_project = 'z2z/target.zip',
+ target_storage_type = 'zip',
+ empty_folders = False)
+
+ self._run_test_export_project_to_project(
+ source_project = 'z2z/source_ef.zip',
+ source_storage_type = 'zip',
+ target_project = 'z2z/target_ef.zip',
+ target_storage_type = 'zip',
+ empty_folders = True)
+
+ def test_export_file_to_zip(self):
+ self._run_test_export_project_to_project(
+ source_project = 'f2z/source',
+ source_storage_type = 'file',
+ target_project = 'f2z/target.zip',
+ target_storage_type = 'zip',
+ empty_folders = False)
+
+ self._run_test_export_project_to_project(
+ source_project = 'f2z/source_ef',
+ source_storage_type = 'file',
+ target_project = 'f2z/target_ef.zip',
+ target_storage_type = 'zip',
+ empty_folders = True)
+
+ def test_export_zip_to_file(self):
+ self._run_test_export_project_to_project(
+ source_project = 'z2f/source.zip',
+ source_storage_type = 'zip',
+ target_project = 'z2f/target',
+ target_storage_type = 'file',
+ empty_folders = False)
+
+ self._run_test_export_project_to_project(
+ source_project = 'z2f/source_ef.zip',
+ source_storage_type = 'zip',
+ target_project = 'z2f/target_ef',
+ target_storage_type = 'file',
+ empty_folders = True)
+
+ def _run_test_multi_export(self, export_dir, export_format, config_args,
+ expected_cpfs=None, expected_dirs=None):
+ self.assertFalse(expected_cpfs is None and expected_dirs is None,
+ "Only one of expected_cpfs or expected_dirs can be specified!")
+ self.assertFalse(expected_cpfs is None and expected_dirs is None,
+ "Either expected_cpfs or expected_dirs must be specified!")
+
+ EXPORT_DIR = os.path.join(TEMP_DIR, export_dir)
+ self.remove_if_exists(EXPORT_DIR)
+
+ self.set_modification_reference_time(TEST_PROJECT_CPF)
+ cmd = '%(cmd)s -p "%(project)s" %(args)s --export-dir "%(export_dir)s" --export-format %(export_format)s' \
+ % {'cmd' : get_cmd('export'),
+ 'project' : TEST_PROJECT_CPF,
+ 'args' : config_args,
+ 'export_dir' : EXPORT_DIR,
+ 'export_format' : export_format}
+ out = self.run_command(cmd)
+ self.assert_not_modified(TEST_PROJECT_CPF)
+
+ if expected_cpfs:
+ for cpf_name, config_root in expected_cpfs:
+ path = os.path.join(EXPORT_DIR, cpf_name)
+ self.assert_exists_and_contains_something(path)
+ self.assert_zip_entry_exists(path, config_root)
+ else:
+ for dir_name, config_root in expected_dirs:
+ path = os.path.join(EXPORT_DIR, dir_name)
+ self.assert_exists_and_contains_something(path)
+ self.assert_exists_and_contains_something(os.path.join(path, config_root))
+
+ def test_export_multiple_cpfs(self):
+ self._run_test_multi_export(
+ export_dir = 'multiexport/cpfs',
+ export_format = 'cpf',
+ config_args = '--configuration root1.confml '\
+ '--configuration root3.confml',
+ expected_cpfs = [('root1.cpf', 'root1.confml'),
+ ('root3.cpf', 'root3.confml')])
+
+ def test_export_multiple_dirs(self):
+ self._run_test_multi_export(
+ export_dir = 'multiexport/dirs',
+ export_format = 'dir',
+ config_args = '--configuration root1.confml '\
+ '--configuration root3.confml',
+ expected_dirs = [('root1/', 'root1.confml'),
+ ('root3/', 'root3.confml')])
+
+ def test_export_multiple_dirs_with_added_layers(self):
+ self._run_test_multi_export(
+ export_dir = 'multiexport/dirs_with_added_layers',
+ export_format = 'dir',
+ config_args = '--configuration root1.confml '\
+ '--configuration root3.confml '\
+ '--add new/layer1/root.confml '\
+ '--add new/layer2/root.confml ',
+ expected_dirs = [('root1/', 'root1.confml'),
+ ('root3/', 'root3.confml')])
+ # Check that the added layers have really been added to the exported
+ # projects
+ def check(path):
+ path = os.path.join(TEMP_DIR, 'multiexport/dirs_with_added_layers', path)
+ self.assert_exists_and_contains_something(path)
+ check('root1/new/layer1/root.confml')
+ check('root1/new/layer2/root.confml')
+ check('root3/new/layer1/root.confml')
+ check('root3/new/layer2/root.confml')
+
+ # Check that the configuration root contains the added layers
+ file_path = os.path.join(TEMP_DIR, 'multiexport/dirs_with_added_layers/root1/root1.confml')
+ data = self.read_data_from_file(file_path)
+ self.assertTrue('href="Layer1/root.confml"' in data)
+ self.assertTrue('href="new/layer1/root.confml"' in data)
+ self.assertTrue('href="new/layer2/root.confml"' in data)
+
+ file_path = os.path.join(TEMP_DIR, 'multiexport/dirs_with_added_layers/root3/root3.confml')
+ data = self.read_data_from_file(file_path)
+ self.assertTrue('href="Layer1/root.confml"' in data)
+ self.assertTrue('href="Layer2/root.confml"' in data)
+ self.assertTrue('href="Layer3/root.confml"' in data)
+ self.assertTrue('href="new/layer1/root.confml"' in data)
+ self.assertTrue('href="new/layer2/root.confml"' in data)
+
+ def test_export_multiple_cpfs_with_wildcard(self):
+ self._run_test_multi_export(
+ export_dir = 'multiexport/cpfs_wildcard',
+ export_format = 'cpf',
+ config_args = '--config-wildcard root*.confml',
+ expected_cpfs = [('root1.cpf', 'root1.confml'),
+ ('root2.cpf', 'root2.confml'),
+ ('root3.cpf', 'root3.confml'),
+ ('root4.cpf', 'root4.confml'),
+ ('root5.cpf', 'root5.confml')])
+
+ def test_export_multiple_cpfs_with_regex(self):
+ self._run_test_multi_export(
+ export_dir = 'multiexport/cpfs_regex',
+ export_format = 'cpf',
+ config_args = '--config-regex root[14].confml',
+ expected_cpfs = [('root1.cpf', 'root1.confml'),
+ ('root4.cpf', 'root4.confml')])
+
+
+class TestExportInvalidArgs(BaseTestCase):
+
+ def _run_test_invalid_args(self, args, expected_msg):
+ cmd = '%s -p "%s" %s' \
+ % (get_cmd('export'), TEST_PROJECT_CPF, args)
+ # Note: The following run_command() should really expect the
+ # return code 2, but for some reason when running from the
+ # standalone test set, the return value is 0
+ out = self.run_command(cmd, expected_return_code = None)
+ self.assertTrue(expected_msg in out,
+ "Expected message '%s' not in output.\nOutput:\n%s" % (expected_msg, out))
+
+ def test_export_format_without_export_dir(self):
+ self._run_test_invalid_args(
+ '-c root1.confml --export-format cpf',
+ "error: --export-format can only be used in conjunction with --export-dir")
+
+ def test_remote_storage_and_export_dir(self):
+ self._run_test_invalid_args(
+ '-c root1.confml --remote jojo.cpf --export-dir test/',
+ "error: --export-dir and --remote cannot be used at the same time")
+
+ def test_unknown_export_format(self):
+ self._run_test_invalid_args(
+ '-c root1.confml --export-dir test/ --export-format foo',
+ "error: Invalid export format 'foo'")
+
+ def test_export_dir_but_no_configurations(self):
+ self._run_test_invalid_args(
+ '--export-dir test/',
+ "error: Use of --export-dir requires at least one configuration to be specified")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_generate.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_generate.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,277 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+##
+# @author Teemu Rytkonen
+
+import sys, os, shutil, unittest
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation import zip_dir
+from scripttest_common import get_cmd
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testproject = os.path.join(ROOT_PATH,'test_project.cpf')
+rootconf = 'root3.confml'
+
+class TestGenerate(BaseTestCase):
+
+ def test_get_help(self):
+ cmd = '%s -h' % get_cmd('generate')
+ out = self.run_command(cmd)
+ lines = out.split('\r\n')
+ self.assertTrue('Options:' in lines)
+ self.assertTrue(' Generate options:' in lines)
+
+ def test_generate(self):
+ self.set_modification_reference_time(testproject)
+ OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/gen1/output')
+ self.remove_if_exists(OUTPUT_DIR)
+ cmd = '%s -p "%s" -c "%s" -o "%s"' % (get_cmd('generate'),testproject,rootconf,OUTPUT_DIR)
+ out = self.run_command(cmd)
+ self.assert_exists_and_contains_something(OUTPUT_DIR)
+
+ self.assert_not_modified(testproject)
+
+ def test_generate_with_report(self):
+ self.set_modification_reference_time(testproject)
+ OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/gen2/output')
+ REPORT_FILE = os.path.join(ROOT_PATH, 'temp/gen2/report.html')
+ self.remove_if_exists([OUTPUT_DIR, REPORT_FILE])
+ cmd = '%s -p "%s" -c "%s" -o "%s" -r "%s"' % (get_cmd('generate'),testproject,rootconf, OUTPUT_DIR, REPORT_FILE)
+ out = self.run_command(cmd)
+ self.assert_exists_and_contains_something(OUTPUT_DIR)
+ self.assert_exists_and_contains_something(REPORT_FILE)
+
+ self.assert_not_modified(testproject)
+
+ def test_generate_with_report_using_custom_template(self):
+ self._run_test_generate_with_report_using_custom_template(
+ output_dir = 'temp/gen3/output',
+ report_file = 'temp/gen3/report.csv',
+ template_path = 'template.csv')
+
+ def test_generate_with_report_using_custom_template_in_relative_dir(self):
+ self._run_test_generate_with_report_using_custom_template(
+ output_dir = 'temp/gen4/output',
+ report_file = 'temp/gen4/report.csv',
+ template_path = 'test_template/template2.csv')
+
+ def test_generate_with_report_using_custom_template_in_relative_dir2(self):
+ self._run_test_generate_with_report_using_custom_template(
+ output_dir = 'temp/gen5/output',
+ report_file = 'temp/gen5/report.csv',
+ template_path = '../tests/test_template/template2.csv')
+
+ def test_generate_with_report_using_custom_template_in_absolute_dir(self):
+ self._run_test_generate_with_report_using_custom_template(
+ output_dir = 'temp/gen6/output',
+ report_file = 'temp/gen6/report.csv',
+ template_path = os.path.join(ROOT_PATH,'test_template/template2.csv'))
+
+ def _run_test_generate_with_report_using_custom_template(self,
+ output_dir, report_file, template_path, project=testproject):
+
+ # Since we are testing also relative paths here, we need
+ # to run the test in the same directory as the script
+ orig_workdir = os.getcwd()
+ os.chdir(ROOT_PATH)
+ try:
+ self.set_modification_reference_time(project)
+ self.remove_if_exists([output_dir, report_file])
+ cmd = '%s -p "%s" -c "%s" -o "%s" -r "%s" -t "%s"' % (get_cmd('generate'),project,rootconf, output_dir, report_file, template_path)
+ out = self.run_command(cmd)
+ self.assert_exists_and_contains_something(output_dir)
+ self.assert_exists_and_contains_something(report_file)
+ self.assert_not_modified(project)
+ finally:
+ os.chdir(orig_workdir)
+
+ def test_generate_with_report_and_invalid_refs_in_data(self):
+ self._run_test_generate_with_report_using_custom_template(
+ project = os.path.join(ROOT_PATH, 'testdata/generate/test_project_invalid_data_refs.zip'),
+ output_dir = 'temp/gen7/output',
+ report_file = 'temp/gen7/report.csv',
+ template_path = os.path.join(ROOT_PATH,'test_template/template2.csv'))
+
+class TestGenerateAllImplsOnLastLayer(BaseTestCase):
+
+ def _prepare_workdir(self, workdir):
+ workdir = os.path.join(ROOT_PATH, workdir)
+ self.recreate_dir(workdir)
+
+ # Any needed extra preparation can be done here
+
+ return workdir
+
+ def test_generate_all_impls_on_last_layer_on_file_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "generation_test_project")
+ self.assert_exists_and_contains_something(project_dir)
+ self._run_test_generate_all_impls_on_last_layer('temp/gen_ll1', project_dir)
+
+ def test_generate_all_impls_on_last_layer_on_zip_storage(self):
+ project_dir = os.path.join(ROOT_PATH, "generation_test_project")
+ self.assert_exists_and_contains_something(project_dir)
+
+ project_zip = os.path.join(ROOT_PATH, "temp/generation_test_project.zip")
+ self.remove_if_exists(project_zip)
+ zip_dir.zip_dir(project_dir, project_zip, [zip_dir.SVN_IGNORE_PATTERN])
+ self.assert_exists_and_contains_something(project_zip)
+
+ self._run_test_generate_all_impls_on_last_layer('temp/gen_ll2', project_zip)
+
+ def test_generate_all_impls_on_last_layer_on_file_storage_with_report(self):
+ project_dir = os.path.join(ROOT_PATH, "generation_test_project")
+ self.assert_exists_and_contains_something(project_dir)
+
+ # Create a temp workdir and go there to run the test
+ orig_workdir = os.getcwd()
+ workdir = self._prepare_workdir('temp/gen_ll3')
+ os.chdir(workdir)
+
+ try:
+ cmd = '%s -p "%s" --output output --layer -1 --add-setting-file imaker_variantdir.cfg --report report.html' % (get_cmd('generate'), project_dir)
+ self.run_command(cmd)
+ finally:
+ os.chdir(orig_workdir)
+
+ ACTUAL_REPORT = os.path.join(ROOT_PATH, 'temp/gen_ll3/report.html')
+ EXPECTED_REPORT = os.path.join(ROOT_PATH, "testdata/generate/expected_report.html")
+
+ ignores = [
+ r'\s*Report generated \s*.* \s* ',
+ r'\s*Generation duration \s*.* \s* ',
+ r'',
+ r'\s*Project \s*.* \s* ',
+ r'\s*Working directory \s*.* \s* ',
+ ]
+
+ self.assert_file_contents_equal(ACTUAL_REPORT, EXPECTED_REPORT, ignores)
+
+ def _run_test_generate_all_impls_on_last_layer(self, workdir, project):
+ # Create a temp workdir and go there to run the test
+ orig_workdir = os.getcwd()
+ workdir = self._prepare_workdir(workdir)
+ os.chdir(workdir)
+
+ try:
+ cmd = '%s -p "%s" --output output --layer -1 --add-setting-file imaker_variantdir.cfg' % (get_cmd('generate'), project)
+ print self.run_command(cmd)
+
+ EXPECTED_DIR = os.path.join(ROOT_PATH, "testdata/generate/expected")
+ self.assert_dir_contents_equal('output', EXPECTED_DIR, ['.svn'])
+
+ # Check that output has also been generated to the overridden output root directory
+ self.assert_exists_and_contains_something('overridden_output/output_rootdir_test.txt')
+ self.assert_exists_and_contains_something('overridden_output/test_subdir/output_rootdir_test.txt')
+ finally:
+ os.chdir(orig_workdir)
+
+class TestGenerationImplFilteringByTags(BaseTestCase):
+
+ def test_no_tag_filtering(self):
+ self._run_tag_filtering_test(
+ name = 'no_filter',
+ filter = '',
+ expected = ['none', 't1', 't2', 't3', 't1_t2', 't2_t3', 't1_t3', 't1_t2_t3'])
+
+ def test_filter_by_t1(self):
+ self._run_tag_filtering_test(
+ name = 't1',
+ filter = '--impl-tag target:t1',
+ expected = ['t1', 't1_t2', 't1_t3', 't1_t2_t3'])
+
+ def test_filter_by_t2(self):
+ self._run_tag_filtering_test(
+ name = 't2',
+ filter = '--impl-tag target:t2',
+ expected = ['t2', 't1_t2', 't2_t3', 't1_t2_t3'])
+
+ def test_filter_by_t3(self):
+ self._run_tag_filtering_test(
+ name = 't3',
+ filter = '--impl-tag target:t3',
+ expected = ['t3', 't1_t3', 't2_t3', 't1_t2_t3'])
+
+ def test_filter_by_t1_or_t2(self):
+ self._run_tag_filtering_test(
+ name = 't1_or_t2',
+ filter = '--impl-tag target:t1 --impl-tag target:t2',
+ expected = ['t1', 't2', 't1_t2', 't2_t3', 't1_t3', 't1_t2_t3'])
+
+ def test_filter_by_t2_or_t3(self):
+ self._run_tag_filtering_test(
+ name = 't2_or_t3',
+ filter = '--impl-tag target:t2 --impl-tag target:t3',
+ expected = ['t2', 't3', 't1_t2', 't2_t3', 't1_t3', 't1_t2_t3'])
+
+ def test_filter_by_t1_or_t3(self):
+ self._run_tag_filtering_test(
+ name = 't1_or_t3',
+ filter = '--impl-tag target:t1 --impl-tag target:t3',
+ expected = ['t1', 't3', 't1_t2', 't2_t3', 't1_t3', 't1_t2_t3'])
+
+ def test_filter_by_t1_or_t2_or_t3(self):
+ self._run_tag_filtering_test(
+ name = 't1_or_t2_or_t3',
+ filter = '--impl-tag target:t1 --impl-tag target:t2 --impl-tag target:t3',
+ expected = ['t1', 't2', 't3', 't1_t2', 't2_t3', 't1_t3', 't1_t2_t3'])
+
+ def test_filter_by_t1_and_t2(self):
+ self._run_tag_filtering_test(
+ name = 't1_and_t2',
+ filter = '--impl-tag target:t1 --impl-tag target:t2 --impl-tag-policy=AND',
+ expected = ['t1_t2', 't1_t2_t3'])
+
+ def test_filter_by_t2_and_t3(self):
+ self._run_tag_filtering_test(
+ name = 't2_and_t3',
+ filter = '--impl-tag target:t2 --impl-tag target:t3 --impl-tag-policy=AND',
+ expected = ['t2_t3', 't1_t2_t3'])
+
+ def test_filter_by_t1_and_t3(self):
+ self._run_tag_filtering_test(
+ name = 't1_and_t3',
+ filter = '--impl-tag target:t1 --impl-tag target:t3 --impl-tag-policy=AND',
+ expected = ['t1_t3', 't1_t2_t3'])
+
+ def test_filter_by_t1_and_t2_and_t3(self):
+ self._run_tag_filtering_test(
+ name = 't1_and_t2_and_t3',
+ filter = '--impl-tag target:t1 --impl-tag target:t2 --impl-tag target:t3 --impl-tag-policy=AND',
+ expected = ['t1_t2_t3'])
+
+ def _run_tag_filtering_test(self, name, filter, expected):
+ PROJECT = os.path.join(ROOT_PATH, 'tag_filtering_test_project')
+
+ OUTPUT_ROOT = os.path.join(ROOT_PATH, 'temp/gen_tf/', name)
+ OUTPUT = os.path.join(OUTPUT_ROOT, 'out')
+ LOG = os.path.join(OUTPUT_ROOT, 'cone.log')
+ self.remove_if_exists(OUTPUT)
+
+ cmd = '%s -p "%s" --output "%s" --log-file="%s" %s' % (get_cmd('generate'), PROJECT, OUTPUT, LOG, filter)
+ self.run_command(cmd)
+
+ self.assert_exists_and_contains_something(OUTPUT)
+
+ expected_files = sorted([x + '.txt' for x in expected])
+ actual_files = sorted(os.listdir(OUTPUT))
+
+ self.assertEquals(expected_files, actual_files)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_info.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_info.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,228 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys
+import os
+import subprocess
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from scripttest_common import get_cmd
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testproject = os.path.join(ROOT_PATH,'test_project.cpf')
+temp_dir = os.path.join(ROOT_PATH, 'temp/info')
+VALUE_REPORT_PROJECT = os.path.join(ROOT_PATH, 'testdata/info/value_report_project')
+
+class TestInfo(BaseTestCase):
+
+ def test_get_help(self):
+ cmd = '%s -h' % get_cmd('info')
+ out = self.run_command(cmd)
+ lines = out.split('\r\n')
+ self.assertTrue('Options:' in lines)
+ self.assertTrue(' Info options:' in lines)
+
+
+ def test_get_project_info(self):
+ self.set_modification_reference_time(testproject)
+ cmd = '%s -p "%s"' % (get_cmd('info'), testproject)
+ out = self.run_command(cmd)
+
+ lines = out.split('\r\n')
+ self.assertTrue('Configurations in the project.' in lines)
+ self.assertTrue('root1.confml' in lines)
+ self.assertTrue('root2.confml' in lines)
+ self.assertTrue('root3.confml' in lines)
+ self.assertTrue('root4.confml' in lines)
+ self.assertTrue('root5.confml' in lines)
+
+ self.assert_not_modified(testproject)
+
+ def test_api_report(self):
+ EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/api_report.html')
+ REPORT_FILE = os.path.join(temp_dir, 'api_report.html')
+ self.remove_if_exists(REPORT_FILE)
+ cmd = '%s -p "%s" -c root3.confml --report-type api --report "%s"' % (get_cmd('info'), testproject, REPORT_FILE)
+ out = self.run_command(cmd)
+
+ # Ignore the file links, because their value depends on the current directory
+ ignores= [r' .* ']
+ self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE, ignores)
+
+ def test_impl_report(self):
+ EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/impl_report.html')
+ REPORT_FILE = os.path.join(temp_dir, 'impl_report.html')
+ self.remove_if_exists(REPORT_FILE)
+ cmd = '%s -p "%s" -c root3.confml --report-type impl --report "%s"' % (get_cmd('info'), testproject, REPORT_FILE)
+ out = self.run_command(cmd)
+
+ self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
+
+ def test_impl_report_with_impl_containers(self):
+ PROJECT = os.path.join(ROOT_PATH, 'generation_test_project')
+ EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/impl_report_with_containers.html')
+ REPORT_FILE = os.path.join(temp_dir, 'impl_report_with_containers.html')
+ self.remove_if_exists(REPORT_FILE)
+ cmd = '%s -p "%s" -c root.confml --report-type impl --report "%s"' % (get_cmd('info'), PROJECT, REPORT_FILE)
+ out = self.run_command(cmd)
+
+ self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
+
+ def test_content_report(self):
+ EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/content_report.html')
+ REPORT_FILE = os.path.join(temp_dir, 'content_report.html')
+ self.remove_if_exists(REPORT_FILE)
+ cmd = '%s -p "%s" -c root5.confml --report-type content --report "%s"' % (get_cmd('info'), testproject, REPORT_FILE)
+ out = self.run_command(cmd)
+
+ self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
+
+ # --------------------------------------------------
+ # Tests for invalid configuration argument detection
+ # --------------------------------------------------
+
+ def _run_test_invalid_configuration_args(self, config_args, expected_msg):
+ REPORT_FILE = os.path.join(temp_dir, "dummy_report.html")
+ self.remove_if_exists(REPORT_FILE)
+ cmd = '%s -p "%s" %s --report "%s"' \
+ % (get_cmd('info'), VALUE_REPORT_PROJECT, config_args, REPORT_FILE)
+ # Note: The following run_command() should really expect the
+ # return code 2, but for some reason when running from the
+ # standalone test set, the return value is 0
+ out = self.run_command(cmd, expected_return_code = None)
+ self.assertFalse(os.path.exists(REPORT_FILE))
+
+ self.assertTrue(expected_msg in out,
+ "Expected message '%s' not in output ('%s')" % (expected_msg, out))
+
+ def test_invalid_single_configuration(self):
+ self._run_test_invalid_configuration_args(
+ '--configuration nonexistent_root.confml',
+ "No such configuration: nonexistent_root.confml")
+
+ def test_invalid_multi_configuration(self):
+ self._run_test_invalid_configuration_args(
+ '--configuration product_root.confml --configuration nonexistent_root.confml',
+ "No such configuration: nonexistent_root.confml")
+
+ def test_invalid_wildcard_configuration(self):
+ self._run_test_invalid_configuration_args(
+ '--config-wildcard nonexistent*.confml',
+ "No matching configurations for wildcard(s) and/or pattern(s).")
+
+ def test_invalid_regex_configuration(self):
+ self._run_test_invalid_configuration_args(
+ '--config-regex nonexistent.*\\.confml',
+ "No matching configurations for wildcard(s) and/or pattern(s).")
+
+ def test_invalid_view_file(self):
+ self._run_test_invalid_configuration_args(
+ '-c product_root.confml --view-file nonexistent.confml',
+ "No such file: nonexistent.confml")
+
+
+ # ----------------------
+ # Tests for value report
+ # ----------------------
+
+ def _run_test_value_report(self, output, expected, args, rep_type='value'):
+ EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/%s' % expected)
+ REPORT_FILE = os.path.join(temp_dir, output)
+ self.remove_if_exists(REPORT_FILE)
+ cmd = '%s -p "%s" %s --report-type %s --report "%s"' \
+ % (get_cmd('info'), VALUE_REPORT_PROJECT, args, rep_type, REPORT_FILE)
+ out = self.run_command(cmd)
+
+ self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
+
+ def test_value_report_configs_with_wildcard(self):
+ self._run_test_value_report(
+ output = 'value_report_langpacks_wildcard.html',
+ expected = 'value_report_langpacks.html',
+ args = '--config-wildcard product_langpack_*_root.confml')
+
+ def test_value_report_configs_with_regex(self):
+ self._run_test_value_report(
+ output = 'value_report_langpacks_regex.html',
+ expected = 'value_report_langpacks.html',
+ args = '--config-regex product_langpack_\\d{2}_root.confml')
+
+ def test_value_report_multi_config(self):
+ self._run_test_value_report(
+ output = 'value_report_langpacks_regex.html',
+ expected = 'value_report_langpacks.html',
+ args = '-c product_langpack_01_root.confml '\
+ '-c product_langpack_02_root.confml '\
+ '-c product_langpack_03_root.confml')
+
+ def test_value_report_single_config(self):
+ self._run_test_value_report(
+ output = 'value_report_single.html',
+ expected = 'value_report_single.html',
+ args = '--configuration product_root.confml')
+
+ def test_value_report_multi_config_mixed_args(self):
+ self._run_test_value_report(
+ output = 'value_report_multi_mixed.html',
+ expected = 'value_report_multi_mixed.html',
+ args = '-c product_root.confml --config-wildcard product_langpack_*_root.confml')
+
+ def test_value_report_single_config_with_view(self):
+ VIEW_FILE = os.path.join(ROOT_PATH, 'testdata/info/test_view.confml')
+ self._run_test_value_report(
+ output = 'value_report_single_with_view.html',
+ expected = 'value_report_single_with_view.html',
+ args = '--configuration product_root.confml --view-file "%s"' % VIEW_FILE)
+
+ def test_value_report_single_config_with_included_view(self):
+ VIEW_FILE = os.path.join(ROOT_PATH, 'testdata/info/include_test_view.confml')
+ self._run_test_value_report(
+ output = 'value_report_single_with_included_view.html',
+ expected = 'value_report_single_with_view.html',
+ args = '--configuration product_root.confml --view-file "%s"' % VIEW_FILE)
+
+ def test_value_report_csv(self):
+ self._run_test_value_report(
+ output = 'value_report.csv',
+ expected = 'value_report.csv',
+ args = '--config-wildcard product_langpack_*_root.confml',
+ rep_type = 'value_csv')
+
+ def test_value_report_csv_with_special_chars(self):
+ self._run_test_value_report(
+ output = 'value_report_special_chars.csv',
+ expected = 'value_report_special_chars.csv',
+ args = '--configuration csv_test_root.confml',
+ rep_type = 'value_csv')
+
+ def test_value_report_custom_template(self):
+ TEMPLATE_FILE = os.path.join(ROOT_PATH, 'testdata/info/custom_value_report_template.html')
+ EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/value_report_custom.html')
+ REPORT_FILE = os.path.join(temp_dir, 'value_report_custom.html')
+ self.remove_if_exists(REPORT_FILE)
+ cmd = '%s -p "%s" --template "%s" --report "%s" -c product_root.confml' \
+ % (get_cmd('info'), VALUE_REPORT_PROJECT, TEMPLATE_FILE, REPORT_FILE)
+ out = self.run_command(cmd)
+
+ self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_merge.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_merge.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,375 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import os
+import shutil
+import zipfile
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation import unzip_file
+from scripttest_common import get_cmd
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata/merge')
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp/merge')
+TEST_PROJECT_CPF = os.path.join(ROOT_PATH, 'test_project.cpf')
+TEST_VARIANT_CPF = os.path.join(ROOT_PATH, 'test_variant.cpf')
+
+TEST_VARIANT_CPF_V1 = os.path.join(TESTDATA_DIR, 'test_variant_v1.cpf')
+TEST_VARIANT_CPF_V2 = os.path.join(TESTDATA_DIR, 'test_variant_v2.cpf')
+
+
+class TestMerge(BaseTestCase):
+
+ def _prepare_workdir_with_project(self, workdir, expected_zip=None):
+ """
+ Prepare a working directory for running a test.
+ @param workdir: Sub-directory of the workdir.
+ @param expected_zip: Zip file containing expected data that should
+ be extracted under the workdir, can be None. The path should be
+ relative to testdata/merge.
+ @return: Tuple (test_project_abs, expected_dir_abs). expected_dir_abs
+ will be None if expected_zip was None.
+ """
+ workdir = os.path.join(TEMP_DIR, workdir)
+ self.recreate_dir(workdir)
+
+ # Unzip the test project
+ test_project_dir = os.path.join(workdir, 'test_project')
+ unzip_file.unzip_file(TEST_PROJECT_CPF, test_project_dir, delete_if_exists=True)
+
+ # Check that it was unzipped correctly
+ paths = [
+ "Layer1/", "Layer2/","Layer3/", "Layer4/", "Layer5/",
+ "root1.confml", "root2.confml", "root3.confml", "root4.confml", "root5.confml"
+ ]
+ for path in paths:
+ self.assert_exists_and_contains_something(os.path.join(test_project_dir, path))
+
+ expected_dir = None
+ # Unzip the expected data
+ if expected_zip:
+ expected_zip = os.path.join(TESTDATA_DIR, expected_zip)
+ expected_dir = os.path.join(workdir, 'expected')
+ unzip_file.unzip_file(expected_zip, expected_dir)
+
+ return test_project_dir, expected_dir
+
+ def test_get_help(self):
+ cmd = '%s -h' % get_cmd('merge')
+ out = self.run_command(cmd)
+ lines = out.split('\r\n')
+ self.assertTrue('Options:' in lines)
+ self.assertTrue(' Merge options:' in lines)
+
+ def test_merge_cpf_last_layer_to_project(self):
+ project_dir, expected_dir = self._prepare_workdir_with_project('last_layer_from_cpf', 'last_layer_expected.zip')
+
+ self.set_modification_reference_time(project_dir)
+ self.set_modification_reference_time(TEST_VARIANT_CPF)
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -1 -v 5' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF)
+ self.run_command(cmd)
+
+ self.assert_modified(project_dir)
+ self.assert_not_modified(TEST_VARIANT_CPF)
+ self.assert_dir_contents_equal(expected_dir, project_dir)
+
+ def test_merge_cpf_last_layer_to_project_with_rename(self):
+ project_dir, expected_dir = self._prepare_workdir_with_project('last_layer_from_cpf_rename', 'last_layer_rename_expected.zip')
+
+ self.set_modification_reference_time(project_dir)
+ self.set_modification_reference_time(TEST_VARIANT_CPF)
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -1 -v 5 --rename' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF)
+ self.run_command(cmd)
+
+ self.assert_modified(project_dir)
+ self.assert_not_modified(TEST_VARIANT_CPF)
+ self.assert_dir_contents_equal(expected_dir, project_dir)
+
+ def test_merge_cpf_multiple_last_layers_to_project(self):
+ project_dir, expected_dir = self._prepare_workdir_with_project('multiple_last_layers_from_cpf', 'multiple_last_layers_expected.zip')
+
+ self.set_modification_reference_time(project_dir)
+ self.set_modification_reference_time(TEST_VARIANT_CPF)
+ # Pass the merged layers in random order to check that it doesn't affect
+ # the output
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -3 -l -1 -l -2 -v 5' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF)
+ self.run_command(cmd)
+
+ self.assert_modified(project_dir)
+ self.assert_not_modified(TEST_VARIANT_CPF)
+ self.assert_dir_contents_equal(expected_dir, project_dir)
+
+ def test_merge_cpf_multiple_mixed_layers_to_project(self):
+ project_dir, expected_dir = self._prepare_workdir_with_project('mixed_multiple_last_layers_from_cpf', 'multiple_last_layers_expected.zip')
+
+ self.set_modification_reference_time(project_dir)
+ self.set_modification_reference_time(TEST_VARIANT_CPF)
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -3 -l -1 -l 4 -l 5 -v 5' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF)
+ self.run_command(cmd)
+
+ self.assert_modified(project_dir)
+ self.assert_not_modified(TEST_VARIANT_CPF)
+ self.assert_dir_contents_equal(expected_dir, project_dir)
+
+ def test_merge_layer_to_cpf(self):
+ project_cpf = os.path.join(ROOT_PATH, "temp/merge/layer_to_cpf/project.cpf")
+ self.create_dir_for_file_path(project_cpf)
+ shutil.copy2(TEST_PROJECT_CPF, project_cpf)
+
+ self.set_modification_reference_time(project_cpf)
+ self.set_modification_reference_time(TEST_VARIANT_CPF)
+
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -1 -v 5' % (get_cmd('merge'), project_cpf, TEST_VARIANT_CPF)
+ self.run_command(cmd)
+
+ def check(entry):
+ zf = zipfile.ZipFile(project_cpf, "r")
+ try: self.assertTrue(entry in zf.namelist(), "Entry '%s' not in zip file '%s'" % (entry, project_cpf))
+ finally: zf.close()
+ check('variant/root.confml')
+ check('variant/confml/data.confml')
+ check('variant/content/empty/')
+
+ self.assertEquals(
+ self.get_xinclude_list(self.read_data_from_zip_file(project_cpf, "root5.confml")),
+ ["Layer1/root.confml",
+ "Layer2/root.confml",
+ "Layer3/root.confml",
+ "Layer4/root.confml",
+ "Layer5/root.confml",
+ "variant/root.confml"])
+
+ self.assert_modified(project_cpf)
+ self.assert_not_modified(TEST_VARIANT_CPF)
+
+ def test_merge_cpf_last_layer_two_versions(self):
+ project_dir, expected_dir = self._prepare_workdir_with_project('last_layer_two_versions', 'last_layer_variant_v1_v2_expected.zip')
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -1' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF_V1)
+ self.run_command(cmd)
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -1' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF_V2)
+ self.run_command(cmd)
+ self.assert_dir_contents_equal(expected_dir, project_dir)
+
+ def test_merge_cpf_last_layer_two_versions_overwrite_layer(self):
+ project_dir, expected_dir = self._prepare_workdir_with_project('last_layer_two_versions_overwrite', 'last_layer_variant_v2_expected.zip')
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -1 --merge-policy overwrite-layer' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF_V1)
+ self.run_command(cmd)
+ cmd = '%s -p "%s" -r "%s" -c root5.confml -l -1 --merge-policy overwrite-layer' % (get_cmd('merge'), project_dir, TEST_VARIANT_CPF_V2)
+ self.run_command(cmd)
+ self.assert_dir_contents_equal(expected_dir, project_dir)
+
+ def get_xinclude_list(self, confml_file_data):
+ """
+ Read the XInlude element list from a ConfML file and assert that.
+ @param confml_file_data: The raw binary data of the ConfML file.
+ """
+ root_elem = ElementTree.fromstring(confml_file_data)
+
+ # Make sure that we have a ConfML file
+ self.assertTrue(
+ root_elem.tag in ("{http://www.s60.com/xml/confml/1}configuration", "{http://www.s60.com/xml/confml/2}configuration"),
+ "The root element is not a ConfML configuration element (tag is '%s')" % root_elem.tag)
+
+ # Read the xi:include list
+ result = []
+ for elem in root_elem.findall("{http://www.w3.org/2001/XInclude}include"):
+ result.append(elem.get("href"))
+
+ return result
+
+# =============================================================================
+
+def run_in_workdir(workdir):
+ """
+ Decorator for running asset merge tests in a specific working directory.
+ """
+ workdir_abs = os.path.join(ROOT_PATH, 'temp/merge/assetmerge', workdir)
+
+ def decorate(testmethod):
+ def run_test(self):
+ assert isinstance(self, TestAssetMerge)
+
+ # Prepare the working directory
+ workdir = self.prepare_workdir(workdir_abs)
+
+ # Go into the working directory to run the test
+ orig_workdir = os.getcwd()
+ os.chdir(workdir)
+ try:
+ # Run the test
+ testmethod(self)
+ finally:
+ # Revert back to the original working directory
+ os.chdir(orig_workdir)
+ return run_test
+
+ return decorate
+
+class TestAssetMerge(BaseTestCase):
+ """
+ Tests for merging an asset (basically a single configuration layer) into
+ a specific layer in an existing project.
+ """
+ TESTDATA_ZIP = os.path.join(ROOT_PATH, 'testdata/merge/assetmerge/data.zip')
+ EXPECTED_ZIP = os.path.join(ROOT_PATH, 'testdata/merge/assetmerge/expected.zip')
+
+ def prepare_workdir(self, workdir):
+ """
+ Prepare a working directory with all needed test data into
+ the given sub-dir under the temporary directory.
+ @param workdir: Absolute path to the working directory.
+ """
+ assert os.path.isabs(workdir)
+
+ # Remove the working directory
+ self.remove_if_exists(workdir)
+
+ # Extract asset merge test data into the working dir
+ unzip_file.unzip_file(self.TESTDATA_ZIP, workdir)
+
+ # Extract expected data
+ unzip_file.unzip_file(self.EXPECTED_ZIP, os.path.join(workdir, 'expected'))
+
+ return workdir
+
+ def assert_is_expected(self, subdir):
+ """
+ Assert that the current main_project is equal to the expected data.
+ """
+ current_dir = os.path.abspath('main_project')
+ expected_dir = os.path.abspath(os.path.join('expected', subdir))
+ self.assert_exists_and_contains_something(expected_dir)
+ self.assert_dir_contents_equal(current_dir, expected_dir, ['.svn', '.metadata'])
+
+ @run_in_workdir('merge_asset1')
+ def test_merge_asset1(self):
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset1_v1 --sourcelayer root.confml' % get_cmd('merge'))
+ self.assert_is_expected('asset1_merged')
+
+ @run_in_workdir('merge_and_update_asset1')
+ def test_merge_and_update_asset1(self):
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset1_v1 --sourcelayer root.confml' % get_cmd('merge'))
+ self.assert_is_expected('asset1_merged')
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset1_v2 --sourcelayer root.confml' % get_cmd('merge'))
+ self.assert_is_expected('asset1_merged_and_updated')
+
+ @run_in_workdir('merge_both')
+ def test_merge_both(self):
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset1_v1 --sourcelayer root.confml' % get_cmd('merge'))
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset2_v1 --sourcelayer root.confml' % get_cmd('merge'))
+ self.assert_is_expected('both_merged')
+
+ @run_in_workdir('merge_both_and_update')
+ def test_merge_both_and_update(self):
+
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset1_v1 --sourcelayer root.confml' % get_cmd('merge'))
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset2_v1 --sourcelayer root.confml' % get_cmd('merge'))
+ self.assert_is_expected('both_merged')
+
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset1_v2 --sourcelayer root.confml' % get_cmd('merge'))
+ self.run_command('%s -p main_project --targetlayer assets/test/root.confml -r asset2_v2 --sourcelayer root.confml' % get_cmd('merge'))
+ self.assert_is_expected('both_merged_and_updated')
+
+class TestMergeInvalidParameters(BaseTestCase):
+
+ def _run_test(self, args, expected_msg):
+ if not isinstance(args, basestring):
+ args = ' '.join(args)
+
+ cmd = get_cmd('merge') + ' ' + args
+ # Note: The following run_command() should really expect the
+ # return code 2, but for some reason when running from the
+ # standalone test set, the return value is 0 for some cases
+ # (specifically, the ones that don't use parser.error() to
+ # exit the program)
+ out = self.run_command(cmd, expected_return_code = None)
+
+ self.assertTrue(expected_msg in out,
+ "Expected message '%s' not in output ('%s')" % (expected_msg, out))
+
+ def test_no_remote(self):
+ self._run_test('', "Remote project must be given")
+
+ def test_source_root_and_target_layer(self):
+ self._run_test(
+ "-p x --targetlayer t.confml -r y --sourceconfiguration s.confml",
+ "Cannot merge a configuration into a layer!")
+
+ def test_source_layer_and_target_root(self):
+ self._run_test(
+ "-p x --configuration t.confml -r y --sourcelayer s.confml",
+ "Merging a layer into a configuration is not supported at the moment!")
+
+ def test_source_layer_and_layer_indices(self):
+ self._run_test(
+ ["-p x --configuration t.confml",
+ "-r y --sourcelayer s.confml",
+ "--layer -1 --layer -2"],
+ "Specifying layer indices using --layer is not supported when using --sourcelayer or --targetlayer!")
+
+ def test_target_layer_and_layer_indices(self):
+ self._run_test(
+ ["-p x --targetlayer t.confml",
+ "-r y --sourceconfiguration s.confml",
+ "--layer -1 --layer -2"],
+ "Specifying layer indices using --layer is not supported when using --sourcelayer or --targetlayer!")
+
+ def test_invalid_source_layer(self):
+ source_dir = os.path.join(TEMP_DIR, 'invalid_source_layer/source_proj')
+ target_dir = os.path.join(TEMP_DIR, 'invalid_source_layer/target_proj')
+ self.recreate_dir(source_dir)
+ self.recreate_dir(target_dir)
+ self._run_test('-p "%s" --targetlayer foo/root.confml -r "%s" --sourcelayer foo/bar/root.confml' % (source_dir, target_dir),
+ "Could not merge: Layer root 'foo/bar/root.confml' not found in source project")
+
+ def test_invalid_source_config(self):
+ source_dir = os.path.join(TEMP_DIR, 'invalid_source_root/source_proj')
+ target_dir = os.path.join(TEMP_DIR, 'invalid_source_root/target_proj')
+ self.recreate_dir(source_dir)
+ self.recreate_dir(target_dir)
+ self._run_test('-p "%s" -c foo_root.confml -r "%s" --sourceconfiguration foobar_root.confml' % (source_dir, target_dir),
+ "Could not merge: Configuration root 'foobar_root.confml' not found in source project")
+
+ def test_invalid_merge_policy(self):
+ self._run_test('-p x -r y --merge-policy foopolicy',
+ "Invalid merge policy: foopolicy")
+
+ def test_invalid_source_layer_root(self):
+ self._run_test('-p x -r y --sourcelayer foobar --targetlayer test/foo.confml',
+ "Source layer root should be a .confml file")
+
+ def test_invalid_target_layer_root(self):
+ self._run_test('-p x -r y --sourcelayer test/foo.confml --targetlayer foobar',
+ "Target layer root should be a .confml file")
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_report.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_report.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, shutil, unittest
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation import zip_dir
+from scripttest_common import get_cmd
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TEMP_DIR = os.path.normpath(os.path.join(ROOT_PATH, 'temp/report'))
+TESTDATA_DIR = os.path.normpath(os.path.join(ROOT_PATH, 'testdata/report'))
+TEST_PROJECT = os.path.normpath(os.path.join(TESTDATA_DIR, 'project'))
+
+
+class TestReport(BaseTestCase):
+
+ def _test_get_help(self):
+ cmd = '%s -h' % get_cmd('report')
+ out = self.run_command(cmd)
+ lines = out.split('\r\n')
+ self.assertTrue('Options:' in lines)
+ self.assertTrue(' Report options:' in lines)
+
+ def test_generate_data_files_and_create_reports(self):
+ TEST_DIR = 'test1/'
+
+ _, datafile_rofs3 = self.generate(TEST_DIR + 'out-rofs3', TEST_DIR + 'repdata/rofs3.dat', 'rofs3')
+ _, datafile_uda = self.generate(TEST_DIR + 'out-uda', TEST_DIR + 'repdata/uda.dat', 'uda')
+
+ REPORTS_DIR = os.path.join(TEMP_DIR, TEST_DIR + 'reports')
+ self.create_report([datafile_rofs3], os.path.join(REPORTS_DIR, 'rofs3.txt'))
+ self.create_report([datafile_uda], os.path.join(REPORTS_DIR, 'uda.txt'))
+ self.create_report([datafile_rofs3, datafile_uda], os.path.join(REPORTS_DIR, 'both.txt'))
+
+ EXPECTED_DIR = os.path.join(TESTDATA_DIR, 'expected')
+ self.assert_dir_contents_equal(EXPECTED_DIR, REPORTS_DIR, ['.svn'])
+
+ # Create by giving the directory as input and check
+ REPORT_FILE = os.path.join(TEMP_DIR, TEST_DIR, 'both_from_dir.txt')
+ EXPECTED_FILE = os.path.join(EXPECTED_DIR, 'both.txt')
+ self.create_report_from_dir(os.path.join(TEMP_DIR, TEST_DIR, 'repdata'), REPORT_FILE)
+ self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
+
+ def generate(self, output_dir, report_data_file, target_tag):
+ """
+ Generate output into the given output directory and report data file.
+ @return: Tuple containing the absolute paths to the output directory
+ and report data file.
+ """
+ OUTPUT_DIR = os.path.join(TEMP_DIR, output_dir)
+ REPORT_DATA_FILE = os.path.join(TEMP_DIR, report_data_file)
+ self.remove_if_exists(OUTPUT_DIR)
+
+ cmd = '%s -p "%s" -o "%s" --report-data-output "%s" --impl-tag target:%s' \
+ % (get_cmd('generate'), TEST_PROJECT, OUTPUT_DIR, REPORT_DATA_FILE, target_tag)
+ self.run_command(cmd)
+ self.assert_exists_and_contains_something(OUTPUT_DIR)
+ self.assert_exists_and_contains_something(REPORT_DATA_FILE)
+
+ return OUTPUT_DIR, REPORT_DATA_FILE
+
+ def create_report(self, report_data_files, report_file):
+ """
+ Create a report based on a number of input data files.
+ @return: Absolute path to the created report.
+ """
+ TEMPLATE_FILE = os.path.join(TESTDATA_DIR, 'template.txt')
+ REPORT_FILE = os.path.join(TEMP_DIR, report_file)
+ self.remove_if_exists(REPORT_FILE)
+
+ cmd = '%s --report "%s" --template "%s" ' % (get_cmd('report'), REPORT_FILE, TEMPLATE_FILE)
+ cmd += ' '.join(['--input-data "%s"' % f for f in report_data_files])
+ self.run_command(cmd)
+ self.assert_exists_and_contains_something(REPORT_FILE)
+ return REPORT_FILE
+
+ def create_report_from_dir(self, report_data_dir, report_file):
+ """
+ Create a report based on an input data directory.
+ @return: Absolute path to the created report.
+ """
+ TEMPLATE_FILE = os.path.join(TESTDATA_DIR, 'template.txt')
+ REPORT_FILE = os.path.join(TEMP_DIR, report_file)
+ self.remove_if_exists(REPORT_FILE)
+
+ cmd = '%s --report "%s" --template "%s" --input-data-dir "%s"' \
+ % (get_cmd('report'), REPORT_FILE, TEMPLATE_FILE, report_data_dir)
+ self.run_command(cmd)
+ self.assert_exists_and_contains_something(REPORT_FILE)
+ return REPORT_FILE
+
+if __name__ == '__main__':
+ unittest.main()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/scripts/tests/unittest_update.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_update.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,298 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import string
+import sys
+import os
+import subprocess
+import shutil
+import __init__
+from testautomation.base_testcase import BaseTestCase
+from testautomation import unzip_file
+from scripttest_common import get_cmd
+from cone.public import api
+
+try:
+ from cElementTree import ElementTree
+except ImportError:
+ try:
+ from elementtree import ElementTree
+ except ImportError:
+ try:
+ from xml.etree import cElementTree as ElementTree
+ except ImportError:
+ from xml.etree import ElementTree
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp/update')
+TEST_PROJECT_CPF = os.path.join(ROOT_PATH, 'test_project.cpf')
+
+class TestUpdate(BaseTestCase):
+
+ def test_get_help(self):
+ cmd = '%s -h' % get_cmd('update')
+ out = self.run_command(cmd)
+ lines = out.split('\r\n')
+ self.assertTrue('Options:' in lines)
+ self.assertTrue(' Update options:' in lines)
+
+ def test_add_and_remove_meta_in_filesystem_project(self):
+ TEST_PROJECT_DIR = os.path.join(ROOT_PATH, 'temp/update/project')
+ unzip_file.unzip_file(TEST_PROJECT_CPF, TEST_PROJECT_DIR, delete_if_exists=True)
+
+ rootfile = os.path.join(TEST_PROJECT_DIR, "root5.confml")
+ self._run_test_add_and_remove_meta_in_project(
+ project = TEST_PROJECT_DIR,
+ root_file_reader = lambda: self.read_data_from_file(rootfile))
+
+ def test_add_and_remove_meta_in_cpf(self):
+ cpf = os.path.join(ROOT_PATH, "temp/metadata/project.cpf")
+ self.remove_if_exists(cpf)
+ self.create_dir_for_file_path(cpf)
+ shutil.copy2(TEST_PROJECT_CPF, cpf)
+
+ self._run_test_add_and_remove_meta_in_project(
+ project = cpf,
+ root_file_reader = lambda: self.read_data_from_zip_file(cpf, "root5.confml"))
+
+ def _run_test_add_and_remove_meta_in_project(self, project, root_file_reader):
+ """
+ Run test for adding and removing metadata in a project.
+
+ @param project: Path to the project that is being modified.
+ @param root_file_reader: Function that will be called to read the raw binary
+ data of the configuration project's root ConfML file.
+ """
+ # -------------------------------------
+ # Step 1: Add metadata and description
+ # -------------------------------------
+ self.set_modification_reference_time(project)
+ cmd = ('%s '\
+ '--project "%s" --configuration root5.confml '\
+ '--add-meta owner="test person" '\
+ '--add-meta product="test product" '\
+ '--add-meta date="2009-05-11" '\
+ '--add-cpf-meta product_type="XYZ-123" '\
+ '--add-cpf-meta platform="Platform X" '\
+ '--add-cpf-meta platform_version="1.0.0" '\
+ '--add-desc "Testing description"') % (get_cmd('update'), project)
+ out = self.run_command(cmd)
+ #print out
+ self.assert_modified(project)
+
+
+ # Check that the metadata is correct
+ root_elem = ElementTree.fromstring(root_file_reader())
+
+ desc_elem = root_elem.find("{http://www.s60.com/xml/confml/2}desc")
+ self.assertEquals(desc_elem.text, "Testing description")
+
+ meta_elem = root_elem.find("{http://www.s60.com/xml/confml/2}meta")
+ self.assertEquals(self._get_meta_entry(meta_elem, 'owner'), 'test person')
+ self.assertEquals(self._get_meta_entry(meta_elem, 'product'), 'test product')
+ self.assertEquals(self._get_meta_entry(meta_elem, 'date'), '2009-05-11')
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'product_type'), 'XYZ-123')
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'platform'), 'Platform X')
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'platform_version'), '1.0.0')
+
+
+ # -----------------------------------------------
+ # Step 2: Remove and modify some of the metadata
+ # -----------------------------------------------
+ self.set_modification_reference_time(project)
+ cmd = ('%s '\
+ '--project "%s" --configuration root5.confml '\
+ '--add-meta product="Prod-1" '\
+ '--remove-meta date '\
+ '--add-cpf-meta platform_version=1.0.1 '\
+ '--remove-meta product_type ') % (get_cmd('update'), project)
+ out = self.run_command(cmd)
+ #print out
+ self.assert_modified(project)
+
+ # Check that the metadata is correct
+ root_elem = ElementTree.fromstring(root_file_reader())
+
+ desc_elem = root_elem.find("{http://www.s60.com/xml/confml/2}desc")
+ self.assertEquals(desc_elem.text, "Testing description")
+
+ meta_elem = root_elem.find("{http://www.s60.com/xml/confml/2}meta")
+ self.assertEquals(self._get_meta_entry(meta_elem, 'owner'), 'test person')
+ self.assertEquals(self._get_meta_entry(meta_elem, 'product'), 'Prod-1')
+ self.assertEquals(self._get_meta_entry(meta_elem, 'date'), None)
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'product_type'), None)
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'platform'), 'Platform X')
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'platform_version'), '1.0.1')
+
+
+ # ------------------------------------------------------------
+ # Step 3: Remove the description and the rest of the metadata
+ # ------------------------------------------------------------
+ self.set_modification_reference_time(project)
+ cmd = ('%s '\
+ '--project "%s" --configuration root5.confml '\
+ '--remove-meta owner '\
+ '--remove-meta product '\
+ '--remove-meta platform '\
+ '--remove-meta platform_version '\
+ '--remove-desc ') % (get_cmd('update'), project)
+ out = self.run_command(cmd)
+ #print out
+ self.assert_modified(project)
+
+
+ # Check that the metadata is correct
+ root_elem = ElementTree.fromstring(root_file_reader())
+
+ desc_elem = root_elem.find("{http://www.s60.com/xml/confml/2}desc")
+ self.assertEquals(desc_elem, None)
+
+ meta_elem = root_elem.find("{http://www.s60.com/xml/confml/2}meta")
+ self.assertEquals(0, len(meta_elem.getchildren()))
+
+
+ def _get_meta_entry(self, meta_elem, entry_name):
+ elem = meta_elem.find("{http://www.s60.com/xml/confml/2}%s" % entry_name)
+ if elem != None: return elem.text
+ else: return None
+
+ def _get_cpf_meta_entry(self, meta_elem, entry_name):
+ elem = None
+ for e in meta_elem.findall("{http://www.nokia.com/xml/cpf-id/1}configuration-property"):
+ if e.get('name') == entry_name:
+ elem = e
+ break
+
+ if elem != None: return elem.get('value')
+ else: return None
+
+ def test_add_data_to_cpf(self):
+ # Copy from the test data
+ cpf = os.path.join(ROOT_PATH, "temp/metadata/add_data_test_project.cpf")
+ self.remove_if_exists(cpf)
+ self.create_dir_for_file_path(cpf)
+ shutil.copy2(TEST_PROJECT_CPF, cpf)
+
+ CONFIG = 'root3.confml'
+
+ def get_setting_value(project_location, ref):
+ prj = api.Project(api.Storage.open(project_location, 'r'))
+ try:
+ config = prj.get_configuration(CONFIG)
+ dview = config.get_default_view()
+ feature = dview.get_feature(ref)
+ return feature.get_value()
+ finally:
+ prj.close()
+
+ self.assertEquals(get_setting_value(cpf, 'Feature1.BooleanSetting'), False)
+
+ self.set_modification_reference_time(cpf)
+ cmd = '%s -p "%s" -c %s --add-data Feature1.BooleanSetting=true' % (get_cmd('update'), cpf, CONFIG)
+ self.run_command(cmd)
+ self.assert_modified(cpf)
+
+ self.assertEquals(get_setting_value(cpf, 'Feature1.BooleanSetting'), True)
+
+ def _run_test_add_meta_to_multiple_roots_in_filesystem_project(self, project, args, updated_configs):
+ TEST_PROJECT_DIR = os.path.join(ROOT_PATH, 'temp/update', project)
+ unzip_file.unzip_file(TEST_PROJECT_CPF, TEST_PROJECT_DIR, delete_if_exists=True)
+ self.assert_exists_and_contains_something(TEST_PROJECT_DIR)
+
+ self.set_modification_reference_time(TEST_PROJECT_DIR)
+ cmd = ('%(cmd)s '\
+ '--project "%(project)s" %(args)s '\
+ '--add-meta owner="test person" '\
+ '--add-meta product="test product" '\
+ '--add-cpf-meta product_type="XYZ-123" '\
+ '--add-cpf-meta platform="Platform X" '\
+ '--add-desc "Testing description"')\
+ % {'cmd' : get_cmd('update'),
+ 'project': TEST_PROJECT_DIR,
+ 'args' : args}
+ out = self.run_command(cmd)
+ #print out
+ self.assert_modified(TEST_PROJECT_DIR)
+
+ # Check that the metadata is correct for all roots
+ project = api.Project(api.Storage.open(TEST_PROJECT_DIR, 'r'))
+ for config in project.list_configurations():
+ config_file_path = os.path.join(TEST_PROJECT_DIR, config)
+ root_elem = ElementTree.fromstring(self.read_data_from_file(config_file_path))
+
+ if config in updated_configs:
+ try:
+ desc_elem = root_elem.find("{http://www.s60.com/xml/confml/2}desc")
+ self.assertNotEquals(desc_elem, None)
+ self.assertEquals(desc_elem.text, "Testing description")
+
+ meta_elem = root_elem.find("{http://www.s60.com/xml/confml/2}meta")
+ self.assertEquals(self._get_meta_entry(meta_elem, 'owner'), 'test person')
+ self.assertEquals(self._get_meta_entry(meta_elem, 'product'), 'test product')
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'product_type'), 'XYZ-123')
+ self.assertEquals(self._get_cpf_meta_entry(meta_elem, 'platform'), 'Platform X')
+ except AssertionError:
+ self.fail("Root '%s' was not updated when it should have been!" % config)
+ else:
+ try:
+ desc_elem = root_elem.find("{http://www.s60.com/xml/confml/2}desc")
+ self.assertEquals(desc_elem, None)
+
+ meta_elem = root_elem.find("{http://www.s60.com/xml/confml/2}meta")
+ self.assertEquals(meta_elem, None)
+ except AssertionError:
+ self.fail("Root '%s' was updated when it should not have been!" % config)
+
+ def test_update_multiple_configurations(self):
+ self._run_test_add_meta_to_multiple_roots_in_filesystem_project(
+ project = 'multi_project',
+ args = '-c root2.confml '
+ '-c root4.confml',
+ updated_configs = ['root2.confml',
+ 'root4.confml'])
+
+ def test_update_multiple_configurations_with_wildcard(self):
+ self._run_test_add_meta_to_multiple_roots_in_filesystem_project(
+ project = 'multi_project_wildcard',
+ args = '--config-wildcard root*.confml',
+ updated_configs = ['root1.confml',
+ 'root2.confml',
+ 'root3.confml',
+ 'root4.confml',
+ 'root5.confml'])
+
+ def test_update_multiple_configurations_with_regex(self):
+ self._run_test_add_meta_to_multiple_roots_in_filesystem_project(
+ project = 'multi_project_regex',
+ args = '--config-regex root[135].confml',
+ updated_configs = ['root1.confml',
+ 'root3.confml',
+ 'root5.confml'])
+
+ def test_update_multiple_configurations_with_mixed_args(self):
+ self._run_test_add_meta_to_multiple_roots_in_filesystem_project(
+ project = 'multi_project_mixed_args',
+ args = '-c root2.confml --config-regex root[13].confml',
+ updated_configs = ['root1.confml',
+ 'root2.confml',
+ 'root3.confml'])
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, os.path
+from pkg_resources import require
+require("setuptools")
+from setuptools import setup, find_packages
+from cone import __version__
+
+setup(
+ name = "cone",
+ version = __version__,
+ packages = find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
+ package_data = {'cone.validation': ['confml_xsd/*.xsd', 'implml_xsd/*.xsd']},
+ install_requires = ['Jinja2>=2.1.1', 'simplejson>=2.0.9', 'lxml>=2.2.2'], #FIX THIS: not to try load cone from web
+
+
+ # Project uses reStructuredText, so ensure that the docutils get
+ # installed or upgraded on the target machine
+ #install_requires = ['zipfile'],
+ test_suite = "cone.tests.runtests.collect_suite",
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/setup.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/setup.cfg Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from setuptools import setup, find_packages
+
+setup(
+ name = "cone-testautomation",
+ version = "1.0",
+ packages = find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
+
+ # Project uses reStructuredText, so ensure that the docutils get
+ # installed or upgraded on the target machine
+ #install_requires = ['zipfile'],
+ #test_suite = "cone.tests.runtests.collect_suite",
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine test automation module",
+ license = "Eclipse Public License v1.0",
+ keywords = "cone testautomation",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+ zip_safe = True
+ # could also include long_description, download_url, classifiers, etc.
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/base_testcase.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/base_testcase.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,363 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, re, unittest, shutil, zipfile, filecmp, subprocess
+
+class BaseTestCase(unittest.TestCase):
+ def set_modification_reference_time(self, path):
+ """
+ Set modification reference time for a subsequent call to assert_modified()
+ or assert_not_modified().
+ @param path: The path to use, can be a file or a directory.
+ """
+ if not hasattr(self, '_mod_refs'):
+ self._mod_refs = {}
+
+ if os.path.isdir(path):
+ self._mod_refs[path] = self._get_dir_modtime_dict(path)
+ elif os.path.isfile(path):
+ self._mod_refs[path] = os.stat(path).st_mtime
+ else:
+ self.fail("'%s' does not exist" % path)
+
+ def assert_modified(self, path):
+ """
+ Assert that a given file or directory has been modified since the last
+ call to set_modification_reference_time() with the same path.
+ """
+ self._assert_modification(path, assert_not_modified=False)
+
+ def assert_not_modified(self, path):
+ """
+ Assert that a given file or directory has NOT been modified since the last
+ call to set_modification_reference_time() with the same path.
+ """
+ self._assert_modification(path, assert_not_modified=True)
+
+ def remove_if_exists(self, path_or_paths):
+ """Remove files or directories if they exist.
+ @param path_or_paths: The path to remove. Can also be a list of paths."""
+ if isinstance(path_or_paths, list):
+ paths = path_or_paths
+ else:
+ paths = [path_or_paths]
+
+ for path in paths:
+ if os.path.isdir(path):
+ shutil.rmtree(path)
+ elif os.path.isfile(path):
+ os.remove(path)
+
+ def create_dir(self, path):
+ """Create the given directory if it doesn't exist."""
+ if not os.path.exists(path):
+ os.makedirs(path)
+
+ def recreate_dir(self, path):
+ """Remove the given directory if it exists, and recreate it."""
+ if os.path.exists(path):
+ shutil.rmtree(path)
+ os.makedirs(path)
+
+ def create_dir_for_file_path(self, path):
+ """Create the directories for the given file"""
+ dir = os.path.dirname(path)
+ if dir != '' and not os.path.exists(dir):
+ os.makedirs(dir)
+
+ def assert_exists_and_contains_something(self, path):
+ """
+ Assert that the given path is a file or a directory and contains some data.
+ """
+ if os.path.isdir(path):
+ if len(os.listdir(path)) == 0:
+ self.fail("Path '%s' exists (is a directory) but does not contain anything)" % path)
+ elif os.path.isfile(path):
+ if os.stat(path).st_size == 0:
+ self.fail("Path '%s' exists (is a file) but does not contain anything)" % path)
+ else:
+ self.fail("Path '%s' does not exist" % path)
+
+ def assert_dir_contents_equal(self, dir1, dir2, ignore=[], custom_comparison_functions={}, current_root_dir=''):
+ """
+ Assert recursively that the contents of two directories are equal.
+ @param ignore: List containing names that should be ignored in the comparison (e.g. '.svn').
+ The entries can either be relative, e.g. 'file.txt', which would ignore 'file.txt'
+ in any directory, or they can be absolute, e.g. '/some/dir/file.txt', which would
+ ignore 'file.txt' only under 'some/dir/', relative to the comparison root.
+ @param custom_comparison_functions: Dictionary containing custom comparison functions
+ for files. Each entry in the dict should contain the following contents:
+ Key: The relative path of the file under the directories, e.g.
+ 'some/path/file.txt'
+ Value: The function used to compare the file contents. The function should
+ take as parameters the raw binary data of the files, and should return
+ True if the contents are equal.
+ @param current_root_dir: For internal use.
+ """
+ msg = "Directory contents are not equal ('%s' vs. '%s')\n" % (dir1, dir2)
+
+ ignore_list = []
+ for entry in ignore:
+ if entry.startswith('/'):
+ dirname, entryname = entry.rsplit('/', 1)
+ dirname = dirname.lstrip('/')
+ #print "dirname = %r" % dirname
+ #print "entryname = %r" % entryname
+ #print "current_root_dir = %r" % current_root_dir
+ if dirname == current_root_dir.rstrip('/'):
+ ignore_list.append(entryname)
+ else:
+ ignore_list.append(entry)
+
+ # Compare files with the custom comparison functions if necessary
+ for path, func in custom_comparison_functions.iteritems():
+ dirname = os.path.dirname(path).replace('\\', '/')
+ filename = os.path.basename(path)
+
+ filepath1 = os.path.join(dir1, filename)
+ filepath2 = os.path.join(dir2, filename)
+
+ # Compare if the file is in the current path and they both exist
+ if dirname == current_root_dir and \
+ os.path.isfile(filepath1) and \
+ os.path.isfile(filepath2):
+ comp_result = func(
+ self.read_data_from_file(filepath1),
+ self.read_data_from_file(filepath2))
+ if not comp_result:
+ # The files are not equal -> fail
+ self.fail(msg + "File '%s' differs" % filename)
+ else:
+ # The files are equal -> ignore from dircmp comparison
+ ignore_list.append(filename)
+
+ dcmp = filecmp.dircmp(dir1, dir2, ignore=ignore_list)
+ self.assertEquals(0, len(dcmp.left_only), msg + "Files only on left: %s" % dcmp.left_only)
+ self.assertEquals(0, len(dcmp.right_only), msg + "Files only on right: %s" % dcmp.right_only)
+ self.assertEquals(0, len(dcmp.diff_files), msg + "Differing files: %s" % dcmp.diff_files)
+ self.assertEquals(0, len(dcmp.funny_files), msg + "Funny files: %s" % dcmp.funny_files)
+ # Recurse into sub-directories
+ for d in dcmp.common_dirs:
+ if current_root_dir: cr = current_root_dir + '/' + d
+ else: cr = d
+ self.assert_dir_contents_equal(
+ os.path.join(dir1, d), os.path.join(dir2, d),
+ ignore, custom_comparison_functions, cr)
+
+ def assert_file_contents_equal(self, file1, file2, ignore_patterns=[]):
+ """
+ Assert the the given two files exist and their contents are equal.
+ @param ignore_patterns: List of regular expressions for portions of the
+ file content to ignore in the comparison. The ignored parts are
+ deleted from the files before actual comparison.
+ """
+ self.assertTrue(os.path.exists(file1), "File '%s' does not exist!" % file1)
+ self.assertTrue(os.path.exists(file2), "File '%s' does not exist!" % file2)
+
+ data1 = self.read_data_from_file(file1)
+ data2 = self.read_data_from_file(file2)
+
+ def remove_ignored(data, pattern_list):
+ for i, pattern in enumerate(pattern_list):
+ data = re.sub(pattern, '{{{ignore_%d}}}' % i, data)
+ return data
+ data1 = remove_ignored(data1, ignore_patterns)
+ data2 = remove_ignored(data2, ignore_patterns)
+
+ if data1 != data2:
+ if len(ignore_patterns) > 0:
+ self.write_data_to_file(file1 + '.comparetemp', data1)
+ self.write_data_to_file(file2 + '.comparetemp', data2)
+ self.fail("Data of the files '%s' and '%s' are not equal\nSee *.comparetemp files for the actual data that was compared." % (file1, file2))
+ else:
+ self.fail("Data of the files '%s' and '%s' are not equal" % (file1, file2))
+
+ def assert_file_content_equals(self, filepath, expected_data):
+ """
+ Assert that the content of the given file is equals to the given expected data.
+ """
+ self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath)
+ self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath)
+
+ f = open(filepath, "rb")
+ try: filedata = f.read()
+ finally: f.close()
+
+ if filedata != expected_data:
+ msg = ("The content of the file '%s' is not what was expected!\n" % filepath) +\
+ ("Expected: %r\nActual: %r" % (expected_data, filedata))
+ self.fail(msg)
+
+ def assert_file_contains(self, filepath, data, encoding=None):
+ """
+ Assert that the given file contains the given text somewhere in its contents.
+ @param filepath: Path to the file to check.
+ @param data: The data the file is expected to contain.
+ @param encoding: Encoding used to decode the contents of the file.
+ If None, noe decoding is done.
+ """
+ self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath)
+ self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath)
+
+ f = open(filepath, "rb")
+ try: filedata = f.read()
+ finally: f.close()
+
+ if encoding is not None:
+ filedata = filedata.decode(encoding)
+
+ if not isinstance(data, list):
+ data = [data]
+
+ for entry in data:
+ if not filedata.find(entry) != -1:
+ self.fail("The file '%s' does not contain the data '%s'" % (filepath, entry))
+
+ def assert_file_does_not_contain(self, filepath, data, encoding=None):
+ """
+ Assert that the given file doesn't contain the given text somewhere in its contents.
+ @param filepath: Path to the file to check.
+ @param data: The data the file is expected to not contain.
+ @param encoding: Encoding used to decode the contents of the file.
+ If None, noe decoding is done.
+ """
+ self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath)
+ self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath)
+
+ f = open(filepath, "rb")
+ try: filedata = f.read()
+ finally: f.close()
+
+ if encoding is not None:
+ filedata = filedata.decode(encoding)
+
+ if not isinstance(data, list):
+ data = [data]
+
+ for entry in data:
+ if not filedata.find(entry) == -1:
+ self.fail("The file '%s' contains the data '%s'" % (filepath, entry))
+
+ def read_data_from_file(self, path):
+ """Read the raw binary data from the given file."""
+ f = open(path, "rb")
+ try: return f.read()
+ finally: f.close()
+
+ def read_data_from_zip_file(self, path, entry):
+ """Read the raw binary data from the given ZIP file with the given ZIP entry."""
+ zf = zipfile.ZipFile(path, "r")
+ try: return zf.read(entry)
+ finally: zf.close()
+
+ def write_data_to_file(self, path, data):
+ """Write raw binary data into the given file."""
+ f = open(path, "wb")
+ try: f.write(data)
+ finally: f.close()
+
+ def run_command(self, command, expected_return_code=0):
+ """
+ Run the given command, asserting that it returns the expected value.
+ @param command: The command to run.
+ @param expected_return_code: The expected return code. Can be None if the return
+ code doesn't matter.
+ @return: The command output.
+ """
+ # Using shell=True on windows uses
+ # cmd.exe /c
+ # to run the actual command, and if cmd.exe sees that the first
+ # character in the command is ", it strips that and a trailing ".
+ # For this reason we add quotes to the command to prevent e.g.
+ # "C:\some\command.cmd" --some-arg "xyz"
+ # from becoming
+ # C:\some\command.cmd" --some-arg "xyz
+ if sys.platform == 'win32' and command.startswith('"'):
+ command = '"' + command + '"'
+
+ p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
+ out, err = p.communicate()
+ if expected_return_code is not None:
+ self.assertTrue(p.returncode == expected_return_code,
+ "Could not execute command (%s)\n"\
+ "Return code is not what was expected (expected %d, got %d)\n"\
+ "Output: \n%s" % (command, expected_return_code, p.returncode, out))
+ return out
+
+ # =====================================================
+ # Private helper methods
+ # =====================================================
+
+ def _get_dir_modtime_dict(self, dir_path):
+ """
+ Return a dictionary of all files and directories and their last
+ modification times in a given directory.
+ """
+ refdict = {}
+ for root, dirs, files in os.walk(dir_path):
+ for f in files:
+ path = os.path.join(root, f)
+ refdict[path] = os.stat(path).st_mtime
+ for d in dirs:
+ path = os.path.join(root, d)
+ refdict[path] = os.stat(path).st_mtime
+ return refdict
+
+ def _assert_modification(self, path, assert_not_modified=True):
+ if os.path.isdir(path):
+ if assert_not_modified:
+ self._assert_dir_not_modified(path)
+ else:
+ self.assert_dir_modified(path)
+ elif os.path.isfile(path):
+ if assert_not_modified:
+ self._assert_file_not_modified(path)
+ else:
+ self._assert_file_modified(path)
+ else:
+ self.fail("'%s' does not exist" % path)
+
+ def _assert_dir_not_modified(self, dir_path):
+ refdict = self._mod_refs[dir_path]
+ curdict = self._get_dir_modtime_dict(dir_path)
+
+ # If the keys of the dicts are not the same, the contents of the
+ # dir have been modified (added or removed files/subdirs)
+ self.assertEquals(curdict.keys(), refdict.keys())
+
+ # Compare manually so that assertion error output shows the specific file/dir
+ for path in curdict.iterkeys():
+ self.assertEquals(curdict[path], refdict[path], "File or dir '%s' modified" % path)
+
+ def assert_dir_modified(self, dir_path):
+ refdict = self._mod_refs[dir_path]
+ curdict = self._get_dir_modtime_dict(dir_path)
+
+ self.assertNotEqual(curdict, refdict, "Directory '%s' has not been modified when it was expected to be" % dir_path)
+
+ def _assert_file_not_modified(self, file_path):
+ time1 = self._mod_refs[file_path]
+ time2 = os.stat(file_path).st_mtime
+ self.assertEquals(time1, time2,
+ ("File '%s' was modified when it should not have been "+\
+ "(mod time %f vs. %f)") % (file_path, time1, time2))
+
+ def _assert_file_modified(self, file_path):
+ time1 = self._mod_refs[file_path]
+ time2 = os.stat(file_path).st_mtime
+ self.assertNotEqual(time1, time2,
+ ("File '%s' was modified not when it should have been "+\
+ "(mod time %f vs. %f)") % (file_path, time1, time2))
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/compare_xml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/compare_xml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,219 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys
+import xml.etree.ElementTree as ElementTree
+import unittest
+import traceback
+
+def compare_xml_documents(data1, data2, **kwargs):
+ """
+ Compare two XML documents for equality.
+ @param data1: The raw byte data of the first XML document as a string.
+ @param data2: The raw byte data of the second XML document as a string.
+
+ Keyword arguments:
+ @param check_encoding: If True, the encoding of the documents is checked to be the same.
+ @param ignore_namespace: If True, XML namespaces are ignored in the comparison.
+ @param ignored_empty_tags: List of tags that will be ignored in the comparison if empty,
+ i.e. if the tags is empty on one side and does not exist on the other.
+ @param debug_stream: If not None, the stream where debug messages are printed.
+
+ @return: True if the documents are equal, False if not.
+ """
+
+ check_encoding = kwargs.get('check_encoding', False)
+ ignore_namespaces = kwargs.get('ignore_namespaces', False)
+ debug_stream = kwargs.get('debug_stream', None)
+ ignored_empty_tags = kwargs.get('ignored_empty_tags', [])
+
+ if data1 == data2:
+ if debug_stream: print >>debug_stream, "Raw byte data equal"
+ return True
+
+ if check_encoding:
+ enc1 = _get_xml_encoding(data1)
+ enc2 = _get_xml_encoding(data2)
+ if enc1.lower() != enc2.lower():
+ if debug_stream: print >>debug_stream, "XML encoding is not the same (%s vs. %s)" % (repr(enc1), repr(enc2))
+ return False
+
+ try:
+ et1 = ElementTree.fromstring(data1)
+ except Exception:
+ if debug_stream: print >>debug_stream, "Failure when parsing data1: %s" % traceback.format_exc()
+ return False
+
+ try:
+ et2 = ElementTree.fromstring(data2)
+ except Exception:
+ if debug_stream: print >>debug_stream, "Failure when parsing data2: %s" % traceback.format_exc()
+ return False
+
+ return _xml_elements_equal(et1, et2, ignore_namespaces, debug_stream, '', ignored_empty_tags)
+
+def _xml_elements_equal(elem1, elem2, ignore_namespaces, debug_stream, parent_path, ignored_empty_tags):
+ ds = debug_stream
+
+ elem1_tag = _get_tag(elem1, ignore_namespaces)
+ elem2_tag = _get_tag(elem2, ignore_namespaces)
+
+ full_path1 = parent_path + '/' + elem1_tag
+ full_path2 = parent_path + '/' + elem2_tag
+ if ds and parent_path == '':
+ print >>ds, "Comparing '%s' vs. '%s'" % (full_path1, full_path2)
+
+ if elem1_tag != elem2_tag:
+ if ds and parent_path == '':
+ print >>ds, "Tags don't match"
+ return False
+
+ def strip_string(data):
+ if data == None: return data
+ else: return data.strip(' \n\r\t')
+ text1 = strip_string(elem1.text)
+ text2 = strip_string(elem2.text)
+ if text1 != text2:
+ if ds and parent_path == '':
+ print >>ds, "Element text %s does not match %s" % (repr(text1), repr(text2))
+ return False
+
+ def strip_namespace_attrs(attrib):
+ if not ignore_namespaces:
+ return attrib
+ else:
+ # Strip all attributes with a namespace if namespace are ignored
+ result = {}
+ for key, value in attrib.iteritems():
+ if '{' not in key:
+ result[key] = value
+ return result
+ attrs1 = strip_namespace_attrs(elem1.attrib)
+ attrs2 = strip_namespace_attrs(elem2.attrib)
+ if attrs1 != attrs2:
+ if ds and parent_path == '':
+ print >>ds, "Element attributes don't match (%s vs. %s)" % (repr(attrs1), repr(attrs2))
+ return False
+
+ # Remove ignored empty sub-elements before comparing the sub-elems
+ subelems1 = elem1.getchildren()
+ subelems2 = elem2.getchildren()
+ _remove_ignored_empty_subelems(subelems1, elem2.getchildren(), full_path1, ignore_namespaces, ignored_empty_tags, ds)
+ _remove_ignored_empty_subelems(subelems2, elem1.getchildren(), full_path1, ignore_namespaces, ignored_empty_tags, ds)
+
+ # Compare sub-elements without caring about their document order
+ # NOTE: This approach will not scale well for very large documents
+ len1 = len(elem1.getchildren())
+ len2 = len(elem2.getchildren())
+ if len1 != len2: return False
+ if len1 == 0: return True
+ matched_subelems2 = []
+ for subelem1 in subelems1:
+ matched = False
+ for subelem2 in subelems2:
+ # Try to match the sub-element in elem2 only if it
+ # has not been matched yet
+ if id(subelem2) not in matched_subelems2:
+ if _xml_elements_equal(subelem1, subelem2, ignore_namespaces, ds, full_path1, ignored_empty_tags):
+ matched = True
+ matched_subelems2.append(id(subelem2))
+ break
+ if not matched:
+ if ds:
+ print >>ds, "No match found for element '%s' under '%s'." % (subelem1.tag, full_path1)
+ print >>ds, "Element data:"
+ print >>ds, ElementTree.tostring(subelem1)
+ return False
+
+ # Everything matched
+ return True
+
+def _remove_ignored_empty_subelems(subelems1, subelems2, parent_path, ignore_namespaces, ignored_empty_tags, debug_stream):
+ """Remove ignored empty sub-elements from list subelems1."""
+ ds = debug_stream
+ if ds: print >>ds, "parent_path: %s" % parent_path
+ removed = []
+ for i, subelem1 in enumerate(subelems1):
+ if len(subelem1.getchildren()) > 0:
+ continue
+
+ # See if the tag should be ignored if it doesn't exist on
+ # the other side
+ is_ignored = False
+ for ignored_tag in ignored_empty_tags:
+ if ds: print >>ds, "ignored_tag = %s, tag = %s" % (ignored_tag, parent_path + "/" + _get_tag(subelem1, ignore_namespaces))
+ if ignored_tag == parent_path + "/" + _get_tag(subelem1, ignore_namespaces):
+ is_ignored = True
+ break
+ if not is_ignored:
+ continue
+
+ # See if the tag exists on the other side
+ found = False
+ for subelem2 in subelems2:
+ if _get_tag(subelem1, ignore_namespaces) == _get_tag(subelem2, ignore_namespaces):
+ found = True
+ break
+ if not found:
+ removed.append(i)
+
+ # Sort and reverse the removed list so that deleting starts from the
+ # end and the indices are correct throughout the operation
+ removed.sort()
+ removed = removed[::-1]
+ if len(removed) >= 2:
+ if removed[0] < removed[-1]:
+ raise RuntimeError("Internal error: list in wrong order: %s" % removed)
+
+ for i in removed:
+ del subelems1[i]
+
+def _get_tag(elem, ignore_namespaces):
+ tag = elem.tag
+ if ignore_namespaces:
+ pos = tag.find('}')
+ if pos >= 0:
+ tag = tag[pos + 1:]
+ return tag
+
+def _get_xml_encoding(xml_data):
+ encoding = 'UTF-8'
+ if xml_data.startswith('\xFE\xFF') or xml_data.startswith('\xFF\xFE'):
+ encoding = 'UTF-16'
+
+ # Decode only up to the first 200 bytes (should be enough for the header)
+ decoded_data = xml_data[:200].decode(encoding, 'ignore')
+ if decoded_data.startswith('') + 2]
+ # E.g header = ''
+
+ def get_substr(string, sought_data):
+ pos = string.find(sought_data)
+ if pos >= 0: return string[pos + len(sought_data):]
+ else: return None
+
+ x = get_substr(header, "encoding")
+ if not x: return ''
+ # E.g x = ' = 'UTF-8'?>'
+ x = x.replace(' ', '').replace('\t', '')
+ # E.g x = '='UTF-8'?>'
+ sgl_quoted = get_substr(x, "='")
+ dbl_quoted = get_substr(x, '="')
+ # E.g sgl_quoted = 'UTF-8'?>'
+ if sgl_quoted: return sgl_quoted[:sgl_quoted.find("'")]
+ elif dbl_quoted: return dbl_quoted[:dbl_quoted.find('"')]
+
+ return ''
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/copy_dir.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/copy_dir.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, shutil
+
+def _filter_list(lst, filters):
+ """
+ Filter a list in-place.
+
+ @param lst: The list to filter.
+ @param ignore_functions: List of functions used to check whether an entry
+ should be filtered or not. Each function is given a list entry and
+ should return True or False.
+ """
+ del_entries = []
+ for entry in lst:
+ for func in filters:
+ if func(entry):
+ del_entries.append(entry)
+ break
+ for entry in del_entries:
+ lst.remove(entry)
+
+def copy_dir(source_dir, target_dir, dir_ignore_functions=[], file_ignore_functions=[]):
+ """
+ Copy a directory tree with the possibility of ignoring certain files or directories.
+
+ @param source_dir: The source directory to copy.
+ @param target_dir: The target directory. If the directory already exists, already
+ files will be overwritten.
+ @param dir_ignore_functions: List of filter functions applied on dirs.
+ @param file_ignore_functions: List of filter functions applied on files.
+ """
+ if not os.path.exists(source_dir):
+ raise RuntimeError("Source dir '%s' does not exist!!" % source_dir)
+
+ source_parts_num = len(source_dir.replace('\\', '/').split('/'))
+ target_parts = target_dir.replace('\\', '/').split('/')
+
+ for root, dirs, files in os.walk(source_dir, topdown=True):
+ _filter_list(dirs, dir_ignore_functions)
+ _filter_list(files, file_ignore_functions)
+
+ # Form the target root path
+ current_dir_parts = root.replace('\\', '/').split('/')
+ current_dir_parts = current_dir_parts[source_parts_num:]
+ target_root_parts = [x for x in target_parts]
+ target_root_parts.extend(current_dir_parts)
+
+ # Create the target directory if necessary
+ target_root = '/'.join(target_root_parts)
+ if not os.path.exists(target_root):
+ os.makedirs(target_root)
+ elif not os.path.isdir(target_root):
+ os.remove(target_root)
+ os.makedirs(target_root)
+
+ # Copy files
+ for file in files:
+ src_file = os.path.join(root, file)
+ dst_file = os.path.join(target_root, file)
+
+ # Remove if exists
+ if os.path.exists(dst_file):
+ if os.path.isdir(dst_file): shutil.rmtree(dst_file)
+ else: os.remove(dst_file)
+
+ shutil.copy2(src_file, dst_file)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/setup.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/setup.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+from setuptools import setup, find_packages
+
+setup(
+ name = "cone-tests",
+ version = "1.0",
+ packages = find_packages(),
+ scripts = ['runtests.py'],
+
+ # Project uses reStructuredText, so ensure that the docutils get
+ # installed or upgraded on the target machine
+ #install_requires = ['zipfile'],
+ #test_suite = "cone.tests.runtests.collect_suite",
+
+ package_data = {
+ 'configproject': ['*.*'],
+ },
+
+ # metadata for upload to PyPI
+ author = "Teemu Rytkonen",
+ author_email = "teemu.rytkonen@nokia.com",
+ description = "Configuration Engine test module",
+ license = "Symbian Foundation License v1.0",
+ keywords = "cone test",
+ url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+
+ # could also include long_description, download_url, classifiers, etc.
+)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/testcli.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/testcli.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+from optparse import OptionParser, OptionGroup
+import os
+import sys
+import shutil
+import unittest
+
+def run(suite):
+ parser = OptionParser(version="%%prog %s" % 1.0)
+ parser.add_option("-f","--format",\
+ dest="format",\
+ help="The output format of the test results, which can be either stdout or xml file [stdout|xml]. Default is stdout",\
+ metavar="FORMAT",\
+ default="stdout")
+ parser.add_option("-o","--output",\
+ dest="output",\
+ help="The output directory of xml output. Default is test-results",\
+ metavar="FOLDER",\
+ default="test-results")
+
+ (options, args) = parser.parse_args()
+ results = None
+ if options.format == "stdout":
+ results = unittest.TextTestRunner(verbosity=2).run(suite)
+ elif options.format == "xml":
+ if not os.path.exists(options.output):
+ os.mkdir(options.output)
+ else:
+ shutil.rmtree(options.output)
+ os.mkdir(options.output)
+ runner = unittest.TextTestRunner(None,options.output)#Add support for xmlrunner
+ results = runner.run(suite)
+ print "Output file created %s" % os.path.join(options.output,runner.filename)
+ else:
+ parser.error("Unrecognized output format %s! See --help." % parser.format)
+
+ if results.errors > 0 or results.failures > 0:
+ return -1
+
+
+
+
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/__init__.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest, os, sys
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(os.path.join(ROOT_PATH,'../..'))
+
+# Find all unittest_*.py files in this folder
+import re
+__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
+# Strip .py endings
+__all__ = map(lambda name: name[:-3], __all__)
+
+def collect_suite():
+ suite = unittest.TestSuite()
+ for test_module in __all__:
+ # Load the test module dynamically and add it to the test suite
+ module = __import__(test_module)
+ suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
+ return suite
+
+def runtests():
+ unittest.TextTestRunner(verbosity=2).run(collect_suite())
+
+if __name__ == '__main__':
+ runtests()
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/runtests.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/runtests.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import __init__
+__init__.runtests()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/ignored.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/ignored.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+fdsafda
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/subdir1/subsubdir/test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/subdir1/subsubdir/test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+fdsafda
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/subdir1/test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/subdir1/test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+fdsafda
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/test.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/testdata/zip_dir/test/test.txt Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+fdsafda
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/unittest_compare_xml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/unittest_compare_xml.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,243 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+from testautomation import compare_xml
+
+class TestGetXmlEncoding(unittest.TestCase):
+ def assert_enc_eq(self, encoding, xml_data):
+ self.assertEquals(encoding, compare_xml._get_xml_encoding(xml_data))
+
+ def test_get_encoding(self):
+ self.assert_enc_eq('ASCII', u""" """.encode('ascii', 'xmlcharrefreplace'))
+ self.assert_enc_eq('ISO-8859-1', u""" """.encode('latin1'))
+ self.assert_enc_eq('utf-8', u""" """.encode('utf-8'))
+ self.assert_enc_eq('UTF-16', u""" """.encode('utf-16'))
+ self.assert_enc_eq('', u""" """.encode('utf-8'))
+ self.assert_enc_eq('', u""" """.encode('utf-8'))
+
+class TestCompareXml(unittest.TestCase):
+ REF_DATA = """
+
+ a sub-element
+ another sub-element
+ yet another sub-element
+
+ """
+
+ def assert_comparison_result_equals(self, data1, data2, expected_result, msg=None, **kwargs):
+ class DebugStream:
+ def __init__(self):
+ self.messages = []
+ def write(self, data):
+ self.messages.append(data)
+
+ ds = DebugStream()
+ kwargs['debug_stream'] = ds
+ result = compare_xml.compare_xml_documents(data1, data2, **kwargs)
+ if result != expected_result:
+ d = []
+ if msg != None: d.append(msg + '\n')
+ d.append("Comparison results are not equal (expected %s, got %s)\n" % (expected_result, result))
+ d.append("Debug output:\n")
+ d.extend(ds.messages)
+ self.fail(''.join(d))
+
+ def test_identical(self):
+ self.assert_comparison_result_equals(self.REF_DATA, self.REF_DATA, True)
+
+ def test_different_whitespace(self):
+ DATA = """
+
+a sub-element another sub-element
+yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, True)
+
+ def test_attrs_in_different_order(self):
+ DATA = """
+
+ a sub-element
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, True)
+
+ def test_elements_in_different_order(self):
+ REF_DATA = """
+
+ 1
+ 2
+ 3
+
+
+
+
+ """
+ DATA = """
+
+
+ 3
+ 1
+
+
+ 2
+
+ """
+ self.assert_comparison_result_equals(REF_DATA, DATA, True)
+
+ def test_different_root_contents(self):
+ DATA = """
+
+some text content in root
+ a sub-element
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, False)
+
+ def test_different_subelem_contents(self):
+ DATA = """
+
+ a sub-element (with different content)
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, False)
+
+ def test_different_attrs_in_root(self):
+ DATA = """
+
+ a sub-element (with different content)
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, False)
+
+ def test_missing_attrs_in_root(self):
+ DATA = """
+
+ a sub-element (with different content)
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, False)
+
+ def test_different_attrs_in_subelem(self):
+ DATA = """
+
+ a sub-element (with different content)
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, False)
+
+ def test_different_whitespace_in_subelem_content(self):
+ DATA = """
+
+ a sub-element
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, True)
+
+ def test_ignore_root_namespace(self):
+ DATA = """
+
+ a sub-element
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, True)
+
+ def test_ignore_namespace(self):
+ DATA = """
+
+ a sub-element
+ another sub-element
+ yet another sub-element
+
+ """
+ self.assert_comparison_result_equals(self.REF_DATA, DATA, True, ignore_namespaces=True)
+
+ def test_ignore_empty_tags(self):
+ REF_DATA = """
+
+ a sub-element
+
+ 1
+ 2
+
+
+
+ """
+ DATA = """
+
+ a sub-element
+
+ 1
+ 2
+
+ """
+ self.assert_comparison_result_equals(REF_DATA, DATA, False)
+ self.assert_comparison_result_equals(DATA, REF_DATA, False)
+ self.assert_comparison_result_equals(REF_DATA, DATA, False, ignored_empty_tags=['/rootElem/emptySubElem'])
+ self.assert_comparison_result_equals(DATA, REF_DATA, False, ignored_empty_tags=['/rootElem/emptySubElem'])
+ self.assert_comparison_result_equals(REF_DATA, DATA, False, ignored_empty_tags=['/rootElem/subElem/emptySubElem'])
+ self.assert_comparison_result_equals(DATA, REF_DATA, False, ignored_empty_tags=['/rootElem/subElem/emptySubElem'])
+ self.assert_comparison_result_equals(REF_DATA, DATA, True, ignored_empty_tags=['/rootElem/emptySubElem', '/rootElem/subElem/emptySubElem'])
+ self.assert_comparison_result_equals(DATA, REF_DATA, True, ignored_empty_tags=['/rootElem/emptySubElem', '/rootElem/subElem/emptySubElem'])
+ #self.assert_comparison_result_equals(DATA, REF_DATA, True, ignored_empty_tags=['emptySubElem'])
+ #self.assert_comparison_result_equals(REF_DATA, DATA, False, ignored_empty_tags=[('emptySubElem', 1)])
+ #self.assert_comparison_result_equals(DATA, REF_DATA, False, ignored_empty_tags=[('emptySubElem', 1)])
+ #self.assert_comparison_result_equals(REF_DATA, DATA, False, ignored_empty_tags=[('emptySubElem', 2)])
+ #self.assert_comparison_result_equals(DATA, REF_DATA, False, ignored_empty_tags=[('emptySubElem', 2)])
+ #self.assert_comparison_result_equals(REF_DATA, DATA, True, ignored_empty_tags=[('emptySubElem', 1), ('emptySubElem', 2)])
+ #self.assert_comparison_result_equals(DATA, REF_DATA, True, ignored_empty_tags=[('emptySubElem', 1), ('emptySubElem', 2)])
+
+ def test_check_encoding(self):
+ DATA_DICT = {
+ 'ASCII': u""" """.encode('ascii', 'xmlcharrefreplace'),
+ 'ISO-8859-1': u""" """.encode('latin1'),
+ 'UTF8': u""" """.encode('utf-8'),
+ 'UTF-16': u""" """.encode('utf-16'),
+ 'None1': u""" """.encode('utf-8'),
+ 'None2': u""" """.encode('utf-8'),
+ }
+
+ for key1 in DATA_DICT.keys():
+ for key2 in DATA_DICT.keys():
+ if key1 != key2 and not (key1.startswith('None') or key2.startswith('None')):
+ self.assert_comparison_result_equals(
+ DATA_DICT[key1], DATA_DICT[key2],
+ False, "Encoding check failed for '%s' vs. '%s'" % (key1, key2),
+ check_encoding=True)
+ self.assert_comparison_result_equals(
+ DATA_DICT[key1], DATA_DICT[key2],
+ True, "Comparison without encoding check failed for '%s' vs. '%s'" % (key1, key2),
+ check_encoding=False)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/unittest_utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/unittest_utils.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+from testautomation import utils
+
+class TestHexToBinData(unittest.TestCase):
+ def test_hex_to_bindata(self):
+ try: utils.hex_to_bindata('102')
+ except ValueError: pass
+
+ try: utils.hex_to_bindata('asdfgh')
+ except ValueError: pass
+
+ self.assertEquals(utils.hex_to_bindata(' 00 11 22 33 44 55 66 77 88 99 aA bB cC dD eE fF '),
+ '\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
+
+ DATA = """
+ 00 11 22 33 44 55
+ 66 77 88 99
+ aA bB cC dD eE fF
+ """
+ self.assertEquals(utils.hex_to_bindata(DATA),
+ '\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/tests/unittest_zip_dir.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/tests/unittest_zip_dir.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, unittest, zipfile
+from testautomation import zip_dir
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+test_data_dir = os.path.join(ROOT_PATH, 'testdata/zip_dir/test')
+temp_dir = os.path.join(ROOT_PATH, 'temp/zip_dir')
+
+class TestZipDir(unittest.TestCase):
+ def test_zip_dir(self):
+ zip_file = os.path.join(temp_dir, 'test.zip')
+ if os.path.exists(zip_file):
+ os.remove(zip_file)
+
+ zip_dir.zip_dir(test_data_dir, zip_file, [zip_dir.SVN_IGNORE_PATTERN, r'^ignored.txt$'])
+
+ self.assertTrue(os.path.isfile(zip_file))
+
+ zf = zipfile.ZipFile(zip_file, 'r')
+ namelist = zf.namelist()
+ zf.close()
+
+ expected = [
+ 'test.txt',
+ 'subdir1/test.txt',
+ 'subdir1/empty_dir/',
+ 'subdir1/subsubdir/test.txt',
+ 'subdir2/empty_dir/',
+ ]
+ self.assertEquals(sorted(expected), sorted(namelist))
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/unzip_file.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/unzip_file.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, zipfile, shutil
+
+def unzip_file(file, dir, delete_if_exists=False):
+ if os.path.exists(dir):
+ if delete_if_exists == True:
+ shutil.rmtree(dir)
+ else:
+ raise RuntimeError("Directory '%s' already exists" % dir)
+ if not os.path.exists(file):
+ raise RuntimeError("File '%s' does not exist" % file)
+
+ os.makedirs(dir)
+ zf = zipfile.ZipFile(file)
+
+ try:
+ for name in zf.namelist():
+ if name.endswith('/'):
+ path = os.path.join(dir, name)
+ if not os.path.exists(path):
+ os.makedirs(path)
+ else:
+ path = os.path.join(dir, name)
+ dirname = os.path.dirname(path)
+ if dirname != '' and not os.path.exists(dirname):
+ os.makedirs(dirname)
+ f = open(path, 'wb')
+ try: f.write(zf.read(name))
+ finally: f.close()
+ finally:
+ zf.close()
+
+def unzip_file_if_newer(file, dir):
+ if not os.path.exists(file):
+ raise RuntimeError("File '%s' does not exist" % file)
+
+ if not os.path.exists(dir) or os.stat(file)[8] > os.stat(dir)[8]:
+ unzip_file(file, dir, True)
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/utils.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/utils.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+def hex_to_bindata(hexdata):
+ hexdata = hexdata.replace(' ', '').replace('\r', '').replace('\n', '').replace('\t', '')
+ if len(hexdata) % 2 != 0:
+ raise ValueError("'%s' is not divisible by 2", hexdata)
+ for c in hexdata:
+ if c not in "0123456789abcdefABCDEF":
+ raise ValueError("'%s' is not a valid hex string", hexdata)
+
+ temp = []
+ for i in xrange(len(hexdata) / 2):
+ start = i * 2
+ end = start + 2
+ temp.append(chr(int(hexdata[start:end], 16)))
+ return ''.join(temp)
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/testautomation/testautomation/zip_dir.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/zip_dir.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,76 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, re, zipfile
+
+SVN_IGNORE_PATTERN = r'(.*/|.*\\|^)\.svn(/.*|\\.*|$)'
+
+def zip_dir(source_dir, target_file, ignore_patterns=[]):
+ """
+ Archive the contents of a directory into a zip file.
+ """
+ if not os.path.isdir(source_dir):
+ raise RuntimeError("'%s' does not exist or is not a directory" % dir)
+
+ target_dir = os.path.dirname(target_file)
+ if target_dir != '' and not os.path.exists(target_dir):
+ os.makedirs(target_dir)
+
+ def is_ignored(entry_name):
+ for pat in ignore_patterns:
+ if re.match(pat, entry_name) != None:
+ return True
+ return False
+
+ zf = zipfile.ZipFile(target_file, 'w', compression=zipfile.ZIP_DEFLATED)
+ try:
+ source_dir = os.path.abspath(source_dir).replace('\\', '/')
+ if not source_dir.endswith('/'): source_dir += '/'
+
+ empty_dirs = []
+ for root, dirs, files in os.walk(source_dir):
+ # Construct the ZIP entry name of the current directory
+ root_dir_zip_name = root.replace('\\', '/')[len(source_dir):] + '/'
+
+ if is_ignored(root_dir_zip_name):
+ continue
+
+ # Create a dictionary of the files that should be written to the
+ # ZIP file
+ filtered_files = {}
+ for fname in files:
+ if root_dir_zip_name == '/': zip_name = fname
+ else: zip_name = root_dir_zip_name + fname
+ if not is_ignored(zip_name):
+ filtered_files[zip_name] = os.path.join(root, fname)
+
+ # If the current directory is a sub-directory of an empty directory candidate,
+ # remove the base directory from the sub-directory candidates
+ empty_dirs = filter(lambda n: not root_dir_zip_name.startswith(n), empty_dirs)
+
+ if len(filtered_files) == 0:
+ # If there are no files, the directory is possibly an empty directory
+ # (though it can still contain sub-directories that contain something)
+ empty_dirs.append(root_dir_zip_name)
+ else:
+ for zip_name, path in filtered_files.iteritems():
+ zf.write(path, zip_name, zipfile.ZIP_DEFLATED)
+
+ # Write empty directories
+ for zip_name in empty_dirs:
+ zf.writestr(zip_name, '')
+ finally:
+ zf.close()
\ No newline at end of file
diff -r 000000000000 -r 2e8eeb919028 configurationengine/update_svn_revision.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/update_svn_revision.py Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,53 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+
+import sys, re
+
+if len(sys.argv) not in (2, 3):
+ print "Expected 1 or 2 arguments: "
+ print " - Set revision to the supplied value"
+ print " - Set revision to ''"
+ sys.exit(1)
+
+filename = sys.argv[1]
+
+if len(sys.argv) == 3:
+ svnrevision = sys.argv[2]
+ # Use the revision provided from command line only if it's valid
+ if re.match('^[0-9]+(:[0-9]+)?M?S?$', svnrevision) is None:
+ svnrevision = ''
+else:
+ svnrevision = ''
+
+f = open(filename, "rt")
+lines = f.readlines()
+f.close()
+
+# Replace the line with the svn revision variable
+replaced = False
+for i, line in enumerate(lines):
+ if line.startswith('_svnrevision = "'):
+ lines[i] = '_svnrevision = "%s"' % svnrevision
+ replaced = True
+ else:
+ lines[i] = line.rstrip('\r\n')
+
+if replaced:
+ f = open(filename, "wt")
+ for line in lines:
+ print >>f, line
+ f.close()
+ print "Revision updated to '%s'" % svnrevision
+else:
+ print "Revision not updated: _svnrevision not found"
diff -r 000000000000 -r 2e8eeb919028 configurationengine/windows.properties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/windows.properties Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,1 @@
+os.windows.pythonlocationbase = E:/
\ No newline at end of file