osgi-compendium-4.3.0/ 0000755 0001750 0001750 00000000000 11656061143 014514 5 ustar drazzib drazzib osgi-compendium-4.3.0/LICENSE 0000644 0001750 0001750 00000026136 11405717712 015533 0 ustar drazzib drazzib
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) 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. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
osgi-compendium-4.3.0/src/ 0000755 0001750 0001750 00000000000 11656061143 015303 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/META-INF/ 0000755 0001750 0001750 00000000000 11656061143 016443 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/META-INF/MANIFEST.MF 0000644 0001750 0001750 00000010533 11632153414 020074 0 ustar drazzib drazzib Manifest-Version: 1
Bnd-LastModified: 1315493643159
Bundle-Copyright: Copyright (c) OSGi Alliance (2000, 2011). All Rights R
eserved.
Bundle-Description: OSGi Service Platform Release 4 Version 4.3, Compend
ium Interfaces and Classes for use in compiling bundles.
Bundle-License: http://opensource.org/licenses/apache2.0.php; link="http
://www.apache.org/licenses/LICENSE-2.0"; description="Apache License, V
ersion 2.0"
Bundle-ManifestVersion: 2
Bundle-Name: osgi.cmpn
Bundle-SymbolicName: osgi.cmpn
Bundle-Vendor: OSGi Alliance
Bundle-Version: 4.3.0.201109081654
Created-By: 1.6.0_27 (Apple Inc.)
DynamicImport-Package: *
Export-Package: info.dmtree.registry;uses:="info.dmtree.notification,inf
o.dmtree,org.osgi.framework";version="1.0",info.dmtree.spi;uses:="info.
dmtree";version="1.0",info.dmtree.notification.spi;uses:="info.dmtree.n
otification";version="1.0",info.dmtree.notification;uses:="info.dmtree"
;version="1.0",info.dmtree;version="1.0.2",info.dmtree.security;uses:="
info.dmtree";version="1.0",org.osgi.application;uses:="org.osgi.framewo
rk";version="1.0",org.osgi.jmx.framework;uses:="org.osgi.jmx,javax.mana
gement.openmbean";version="1.5",org.osgi.jmx.service.permissionadmin;ve
rsion="1.2",org.osgi.jmx.service.provisioning;uses:="javax.management.o
penmbean";version="1.2",org.osgi.jmx.service.coordinator;uses:="org.osg
i.jmx,javax.management.openmbean";version="1.0",org.osgi.jmx.service.cm
;uses:="javax.management.openmbean";version="1.3",org.osgi.jmx.service.
useradmin;uses:="org.osgi.jmx,javax.management.openmbean";version="1.1.
1",org.osgi.jmx;uses:="javax.management.openmbean";version="1.0",org.os
gi.service.application;uses:="org.osgi.framework";version="1.1",org.osg
i.service.blueprint.reflect;version="1.0.1",org.osgi.service.blueprint.
container;uses:="org.osgi.service.blueprint.reflect,org.osgi.framework"
;version="1.0.2",org.osgi.service.cm;uses:="org.osgi.framework";version
="1.3",org.osgi.service.component;uses:="org.osgi.framework";version="1
.1",org.osgi.service.component.annotations;version="1.0",org.osgi.servi
ce.coordinator;uses:="org.osgi.framework";version="1.0",org.osgi.servic
e.deploymentadmin.spi;uses:="org.osgi.framework,org.osgi.service.deploy
mentadmin";version="1.0.1",org.osgi.service.deploymentadmin;uses:="org.
osgi.framework";version="1.1",org.osgi.service.device;uses:="org.osgi.f
ramework";version="1.1",org.osgi.service.event;uses:="org.osgi.framewor
k";version="1.3",org.osgi.service.http;uses:="javax.servlet.http,javax.
servlet";version="1.2.1",org.osgi.service.io;uses:="javax.microedition.
io";version="1.0",org.osgi.service.jdbc;uses:="javax.sql";version="1.0"
,org.osgi.service.jndi;uses:="javax.naming.directory,javax.naming";vers
ion="1.0",org.osgi.service.jpa;uses:="javax.persistence";version="1.0",
org.osgi.service.log;uses:="org.osgi.framework";version="1.3",org.osgi.
service.metatype;uses:="org.osgi.framework";version="1.2",org.osgi.serv
ice.monitor;version="1.0",org.osgi.service.prefs;version="1.1.1",org.os
gi.service.provisioning;version="1.2",org.osgi.service.remoteserviceadm
in;uses:="org.osgi.framework";version="1.0.1",org.osgi.service.upnp;ver
sion="1.1",org.osgi.service.useradmin;uses:="org.osgi.framework";versio
n="1.1",org.osgi.service.wireadmin;uses:="org.osgi.framework";version="
1.0.1",org.osgi.util.cdma;uses:="org.osgi.service.condpermadmin,org.osg
i.framework";version="1.0",org.osgi.util.gsm;uses:="org.osgi.service.co
ndpermadmin,org.osgi.framework";version="1.0.1",org.osgi.util.measureme
nt;version="1.0.1",org.osgi.util.mobile;uses:="org.osgi.service.condper
madmin,org.osgi.framework";version="1.0",org.osgi.util.position;uses:="
org.osgi.util.measurement";version="1.0.1",org.osgi.util.tracker;uses:=
"org.osgi.framework";version="1.5",org.osgi.util.xml;uses:="org.osgi.fr
amework,javax.xml.parsers";version="1.0.1"
Import-Package: javax.management.openmbean;resolution:=optional,javax.mi
croedition.io;resolution:=optional,javax.naming;resolution:=optional,ja
vax.naming.directory;resolution:=optional,javax.persistence;resolution:
=optional,javax.servlet;resolution:=optional,javax.servlet.http;resolut
ion:=optional,javax.sql;resolution:=optional,javax.xml.parsers;resoluti
on:=optional,org.osgi.framework;resolution:=optional,org.osgi.service.c
ondpermadmin;resolution:=optional
Tool: Bnd-1.44.0
osgi-compendium-4.3.0/src/info/ 0000755 0001750 0001750 00000000000 11632153414 016233 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/info/dmtree/ 0000755 0001750 0001750 00000000000 11632153414 017513 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/info/dmtree/MetaNode.java 0000644 0001750 0001750 00000041601 11564442770 022066 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
/**
* The MetaNode contains meta data as standardized by OMA DM but extends it
* (without breaking the compatibility) to provide for better DMT data quality
* in an environment where many software components manipulate this data.
*
* The interface has several types of functions to describe the nodes in the
* DMT. Some methods can be used to retrieve standard OMA DM metadata such as
* access type, cardinality, default, etc., others are for data extensions such
* as valid names and values. In some cases the standard behaviour has been
* extended, for example it is possible to provide several valid MIME types, or
* to differentiate between normal and automatic dynamic nodes.
*
* Most methods in this interface receive no input, just return information
* about some aspect of the node. However, there are two methods that behave
* differently, {@link #isValidName} and {@link #isValidValue}. These validation
* methods are given a potential node name or value (respectively), and can
* decide whether it is valid for the given node. Passing the validation methods
* is a necessary condition for a name or value to be used, but it is not
* necessarily sufficient: the plugin may carry out more thorough (more
* expensive) checks when the node is actually created or set.
*
* If a {@code MetaNode} is available for a node, the DmtAdmin must use the
* information provided by it to filter out invalid requests on that node.
* However, not all methods on this interface are actually used for this
* purpose, as many of them (e.g. {@link #getFormat} or {@link #getValidNames})
* can be substituted with the validating methods. For example,
* {@link #isValidValue} can be expected to check the format, minimum, maximum,
* etc. of a given value, making it unnecessary for the DmtAdmin to call
* {@link #getFormat()}, {@link #getMin()}, {@link #getMax()} etc. separately.
* It is indicated in the description of each method if the DmtAdmin does not
* enforce the constraints defined by it - such methods are only for external
* use, for example in user interfaces.
*
* Most of the methods of this class return {@code null} if a certain piece
* of meta information is not defined for the node or providing this information
* is not supported. Methods of this class do not throw exceptions.
*
* @version $Id: c89bb47db0043e3ae9d2dc45ecb0f1f8e7bf73fa $
*/
public interface MetaNode {
/**
* Constant for the ADD access type. If {@link #can(int)} returns
* {@code true} for this operation, this node can potentially be
* added to its parent. Nodes with {@link #PERMANENT} or {@link #AUTOMATIC}
* scope typically do not have this access type.
*/
int CMD_ADD = 0;
/**
* Constant for the DELETE access type. If {@link #can(int)} returns
* {@code true} for this operation, the node can potentially be
* deleted.
*/
int CMD_DELETE = 1;
/**
* Constant for the EXECUTE access type. If {@link #can(int)} returns
* {@code true} for this operation, the node can potentially be
* executed.
*/
int CMD_EXECUTE = 2;
/**
* Constant for the REPLACE access type. If {@link #can(int)} returns
* {@code true} for this operation, the value and other properties of
* the node can potentially be modified.
*/
int CMD_REPLACE = 3;
/**
* Constant for the GET access type. If {@link #can(int)} returns
* {@code true} for this operation, the value, the list of child nodes
* (in case of interior nodes) and the properties of the node can
* potentially be retrieved.
*/
int CMD_GET = 4;
/**
* Constant for representing a permanent node in the tree. This must be
* returned by {@link #getScope} if the node cannot be added, deleted or
* modified in any way through tree operations. Permanent nodes cannot have
* non-permanent nodes as parents.
*/
int PERMANENT = 0;
/**
* Constant for representing a dynamic node in the tree. This must be
* returned by {@link #getScope} for all nodes that are not permanent and
* are not created automatically by the management object.
*/
int DYNAMIC = 1;
/**
* Constant for representing an automatic node in the tree. This must be
* returned by {@link #getScope()} for all nodes that are created
* automatically by the management object. Automatic nodes represent a
* special case of dynamic nodes, so this scope should be mapped to
* {@link #DYNAMIC} when used in an OMA DM context.
*
* An automatic node is usually created instantly when its parent is
* created, but it is also valid if it only appears later, triggered by some
* other condition. The exact behaviour must be defined by the Management
* Object.
*/
int AUTOMATIC = 2;
/**
* Check whether the given operation is valid for this node. If no meta-data
* is provided for a node, all operations are valid.
*
* @param operation One of the {@code MetaNode.CMD_...} constants.
* @return {@code false} if the operation is not valid for this node
* or the operation code is not one of the allowed constants
*/
boolean can(int operation);
/**
* Check whether the node is a leaf node or an internal one.
*
* @return {@code true} if the node is a leaf node
*/
boolean isLeaf();
/**
* Return the scope of the node. Valid values are
* {@link #PERMANENT MetaNode.PERMANENT}, {@link #DYNAMIC MetaNode.DYNAMIC}
* and {@link #AUTOMATIC MetaNode.AUTOMATIC}. Note that a permanent node is
* not the same as a node where the DELETE operation is not allowed.
* Permanent nodes never can be deleted, whereas a non-deletable node can
* disappear in a recursive DELETE operation issued on one of its parents.
* If no meta-data is provided for a node, it can be assumed to be a dynamic
* node.
*
* @return {@link #PERMANENT} for permanent nodes, {@link #AUTOMATIC} for
* nodes that are automatically created, and {@link #DYNAMIC}
* otherwise
*/
int getScope();
/**
* Get the explanation string associated with this node. Can be
* {@code null} if no description is provided for this node.
*
* @return node description string or {@code null} for no description
*/
String getDescription();
/**
* Get the number of maximum occurrences of this type of nodes on the same
* level in the DMT. Returns {@code Integer.MAX_VALUE} if there is no
* upper limit. Note that if the occurrence is greater than 1 then this node
* can not have siblings with different metadata. In other words, if
* different types of nodes coexist on the same level, their occurrence can
* not be greater than 1. If no meta-data is provided for a node, there is
* no upper limit on the number of occurrences.
*
* @return The maximum allowed occurrence of this node type
*/
int getMaxOccurrence();
/**
* Check whether zero occurrence of this node is valid. If no meta-data is
* returned for a node, zero occurrences are allowed.
*
* @return {@code true} if zero occurrence of this node is valid
*/
boolean isZeroOccurrenceAllowed();
/**
* Get the default value of this node if any.
*
* @return The default value or {@code null} if not defined
*/
DmtData getDefault();
/**
* Get the list of MIME types this node can hold. The first element of the
* returned list must be the default MIME type.
*
* All MIME types are considered valid if no meta-data is provided for a
* node or if {@code null} is returned by this method. In this case
* the default MIME type cannot be retrieved from the meta-data, but the
* node may still have a default. This hidden default (if it exists) can be
* utilized by passing {@code null} as the type parameter of
* {@link DmtSession#setNodeType(String, String)} or
* {@link DmtSession#createLeafNode(String, DmtData, String)}.
*
* @return the list of allowed MIME types for this node, starting with the
* default MIME type, or {@code null} if all types are
* allowed
*/
String[] getMimeTypes();
/**
* Get the maximum allowed value associated with a node of numeric format.
* If no meta-data is provided for a node, there is no upper limit to its
* value. This method is only meaningful if the node has integer or float
* format. The returned limit has {@code double} type, as this can be
* used to denote both integer and float limits with full precision. The
* actual maximum should be the largest integer or float number that does
* not exceed the returned value.
*
* The information returned by this method is not checked by DmtAdmin, it
* is only for external use, for example in user interfaces. DmtAdmin only
* calls {@link #isValidValue} for checking the value, its behaviour should
* be consistent with this method.
*
* @return the allowed maximum, or {@code Double.MAX_VALUE} if there
* is no upper limit defined or the node's format is not integer or
* float
*/
double getMax();
/**
* Get the minimum allowed value associated with a node of numeric format.
* If no meta-data is provided for a node, there is no lower limit to its
* value. This method is only meaningful if the node has integer or float
* format. The returned limit has {@code double} type, as this can be
* used to denote both integer and float limits with full precision. The
* actual minimum should be the smallest integer or float number that is
* larger than the returned value.
*
* The information returned by this method is not checked by DmtAdmin, it
* is only for external use, for example in user interfaces. DmtAdmin only
* calls {@link #isValidValue} for checking the value, its behaviour should
* be consistent with this method.
*
* @return the allowed minimum, or {@code Double.MIN_VALUE} if there
* is no lower limit defined or the node's format is not integer or
* float
*/
double getMin();
/**
* Return an array of DmtData objects if valid values are defined for the
* node, or {@code null} otherwise. If no meta-data is provided for a
* node, all values are considered valid.
*
* The information returned by this method is not checked by DmtAdmin, it
* is only for external use, for example in user interfaces. DmtAdmin only
* calls {@link #isValidValue} for checking the value, its behaviour should
* be consistent with this method.
*
* @return the valid values for this node, or {@code null} if not
* defined
*/
DmtData[] getValidValues();
/**
* Get the node's format, expressed in terms of type constants defined in
* {@link DmtData}. If there are multiple formats allowed for the node then
* the format constants are OR-ed. Interior nodes must have
* {@link DmtData#FORMAT_NODE} format, and this code must not be returned
* for leaf nodes. If no meta-data is provided for a node, all applicable
* formats are considered valid (with the above constraints regarding
* interior and leaf nodes).
*
* Note that the 'format' term is a legacy from OMA DM, it is more customary
* to think of this as 'type'.
*
* The formats returned by this method are not checked by DmtAdmin, they
* are only for external use, for example in user interfaces. DmtAdmin only
* calls {@link #isValidValue} for checking the value, its behaviour should
* be consistent with this method.
*
* @return the allowed format(s) of the node
*/
int getFormat();
/**
* Get the format names for any raw formats supported by the node. This
* method is only meaningful if the list of supported formats returned by
* {@link #getFormat()} contains {@link DmtData#FORMAT_RAW_STRING} or
* {@link DmtData#FORMAT_RAW_BINARY}: it specifies precisely which raw
* format(s) are actually supported. If the node cannot contain data in one
* of the raw types, this method must return {@code null}.
*
* The format names returned by this method are not checked by DmtAdmin,
* they are only for external use, for example in user interfaces. DmtAdmin
* only calls {@link #isValidValue} for checking the value, its behaviour
* should be consistent with this method.
*
* @return the allowed format name(s) of raw data stored by the node, or
* {@code null} if raw formats are not supported
*/
String[] getRawFormatNames();
/**
* Checks whether the given value is valid for this node. This method can be
* used to ensure that the value has the correct format and range, that it
* is well formed, etc. This method should be consistent with the
* constraints defined by the {@link #getFormat}, {@link #getValidValues},
* {@link #getMin} and {@link #getMax} methods (if applicable), as the Dmt
* Admin only calls this method for value validation.
*
* This method may return {@code true} even if not all aspects of the
* value have been checked, expensive operations (for example those that
* require external resources) need not be performed here. The actual value
* setting method may still indicate that the value is invalid.
*
* @param value the value to check for validity
* @return {@code false} if the specified value is found to be
* invalid for the node described by this meta-node,
* {@code true} otherwise
*/
boolean isValidValue(DmtData value);
/**
* Return an array of Strings if valid names are defined for the node, or
* {@code null} if no valid name list is defined or if this piece of
* meta info is not supported. If no meta-data is provided for a node, all
* names are considered valid.
*
* The information returned by this method is not checked by DmtAdmin, it
* is only for external use, for example in user interfaces. DmtAdmin only
* calls {@link #isValidName} for checking the name, its behaviour should be
* consistent with this method.
*
* @return the valid values for this node name, or {@code null} if
* not defined
*/
String[] getValidNames();
/**
* Checks whether the given name is a valid name for this node. This method
* can be used for example to ensure that the node name is always one of a
* predefined set of valid names, or that it matches a specific pattern.
* This method should be consistent with the values returned by
* {@link #getValidNames} (if any), the DmtAdmin only calls this method for
* name validation.
*
* This method may return {@code true} even if not all aspects of the
* name have been checked, expensive operations (for example those that
* require external resources) need not be performed here. The actual node
* creation may still indicate that the node name is invalid.
*
* @param name the node name to check for validity
* @return {@code false} if the specified name is found to be invalid
* for the node described by this meta-node, {@code true}
* otherwise
*/
boolean isValidName(String name);
/**
* Returns the list of extension property keys, if the provider of this
* {@code MetaNode} provides proprietary extensions to node meta
* data. The method returns {@code null} if the node doesn't provide
* such extensions.
*
* @return the array of supported extension property keys
*/
String[] getExtensionPropertyKeys();
/**
* Returns the value for the specified extension property key. This method
* only works if the provider of this {@code MetaNode} provides
* proprietary extensions to node meta data.
*
* @param key the key for the extension property
* @return the value of the requested property, cannot be {@code null}
* @throws IllegalArgumentException if the specified key is not supported by
* this {@code MetaNode}
*/
Object getExtensionProperty(String key);
}
osgi-compendium-4.3.0/src/info/dmtree/registry/ 0000755 0001750 0001750 00000000000 11632153414 021363 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/info/dmtree/registry/package-info.java 0000644 0001750 0001750 00000003236 11466514064 024565 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Device Management Tree Registry Package Version 1.0.
*
*
* This package contains the factory class providing access to the different
* Device Management services for non-OSGi applications. The
* {@code DmtServiceFactory} class contained in this package provides methods
* for retrieving {@code NotificationService} and {@code DmtAdmin}
* service implementations.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: info.dmtree.registry; version="[1.0,1.1)"}
*
* @version $Id: 7df579cffa84a035f9198eeda06989cf95f803c9 $
*/
package info.dmtree.registry;
osgi-compendium-4.3.0/src/info/dmtree/registry/packageinfo 0000644 0001750 0001750 00000000014 11405717676 023566 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/info/dmtree/registry/DmtServiceFactory.java 0000644 0001750 0001750 00000007251 11466514064 025637 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.registry;
import info.dmtree.DmtAdmin;
import info.dmtree.notification.NotificationService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* This class is the central access point for Device Management services.
* Applications can use the static factory methods provided in this class to
* obtain access to the different Device Management related services, such as
* the DmtAdmin for manipulating the tree, or the Notification Service for
* sending notifications to management servers.
*
* These methods are not needed in an OSGi environment, clients should retrieve
* the required service objects from the OSGi Service Registry.
*
* @version $Id: 2e571c170e4e61fef5b829c5aed1983afc394070 $
*/
public final class DmtServiceFactory {
private static BundleContext context = null;
/**
* A private constructor to suppress the default public constructor.
*/
private DmtServiceFactory() {}
/**
* This method is used to obtain access to {@code DmtAdmin}, which
* enables applications to manipulate the Device Management Tree.
*
* @return a DmtAdmin service object
*/
public static DmtAdmin getDmtAdmin() {
if(context == null)
throw new IllegalStateException("Cannot retrieve Dmt Admin " +
"service, implementation bundle not started yet.");
ServiceReference dmtAdminRef =
context.getServiceReference(DmtAdmin.class.getName());
if(dmtAdminRef == null)
throw new IllegalStateException("Dmt Admin service not found in " +
"service registry.");
DmtAdmin dmtAdmin = (DmtAdmin) context.getService(dmtAdminRef);
if(dmtAdmin == null)
throw new IllegalStateException("Dmt Admin service not found in " +
"service registry.");
return dmtAdmin;
}
/**
* This method is used to obtain access to {@code NotificationService},
* which enables applications to send asynchronous notifications to
* management servers.
*
* @return a NotificationService service object
*/
public static NotificationService getNotificationService() {
if(context == null)
throw new IllegalStateException("Cannot retrieve Notification " +
"service, implementation bundle not started yet.");
ServiceReference notificationServiceRef =
context.getServiceReference(NotificationService.class.getName());
if(notificationServiceRef == null)
throw new IllegalStateException("Notification service not found " +
"in service registry.");
NotificationService notificationService =
(NotificationService) context.getService(notificationServiceRef);
if(notificationService == null)
throw new IllegalStateException("Notification service not found " +
"in service registry.");
return notificationService;
}
}
osgi-compendium-4.3.0/src/info/dmtree/package-info.java 0000644 0001750 0001750 00000003315 11564442770 022716 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Device Management Tree Package Version 1.0.
*
*
This package contains the public API for the Device Management Tree
* manipulations. Permission classes are provided by the
* {@code info.dmtree.security} package, and DMT plugin interfaces can be found in
* the {@code info.dmtree.spi} package. Asynchronous notifications to remote
* management servers can be sent using the interfaces in the
* {@code info.dmtree.notification} package.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: info.dmtree; version="[1.0,1.1)"}
*
* @version $Id: 09257aa0c6277a1b2c9731b591d26b5ca0e8a96e $
*/
package info.dmtree;
osgi-compendium-4.3.0/src/info/dmtree/DmtIllegalStateException.java 0000644 0001750 0001750 00000005147 11466514064 025272 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2006, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
/**
* Unchecked illegal state exception. This class is used in DMT because
* java.lang.IllegalStateException does not exist in CLDC.
*
* @version $Id: 497b7af9fb2f578792af298367c30e454ac2b104 $
*/
public class DmtIllegalStateException extends RuntimeException {
private static final long serialVersionUID = 2015244852018469700L;
/**
* Create an instance of the exception with no message.
*/
public DmtIllegalStateException() {
super();
}
/**
* Create an instance of the exception with the specified message.
*
* @param message the reason for the exception
*/
public DmtIllegalStateException(String message) {
super(message);
}
/**
* Create an instance of the exception with the specified cause exception
* and no message.
*
* @param cause the cause of the exception
*/
public DmtIllegalStateException(Throwable cause) {
super(cause);
}
/**
* Create an instance of the exception with the specified message and cause
* exception.
*
* @param message the reason for the exception
* @param cause the cause of the exception
*/
public DmtIllegalStateException(String message, Throwable cause) {
super(message, cause);
}
/**
* Returns the cause of this exception or {@code null} if no cause was
* set.
*
* @return The cause of this exception or {@code null} if no cause was
* set.
*/
public Throwable getCause() {
return super.getCause();
}
/**
* Initializes the cause of this exception to the specified value.
*
* @param cause The cause of this exception.
* @return This exception.
* @throws IllegalArgumentException If the specified cause is this
* exception.
* @throws IllegalStateException If the cause of this exception has already
* been set.
* @since 1.0.1
*/
public Throwable initCause(Throwable cause) {
return super.initCause(cause);
}
}
osgi-compendium-4.3.0/src/info/dmtree/DmtException.java 0000644 0001750 0001750 00000063336 11564442770 023006 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
import java.io.PrintStream;
import java.util.Vector;
/**
* Checked exception received when a DMT operation fails. Beside the exception
* message, a {@code DmtException} always contains an error code (one of
* the constants specified in this class), and may optionally contain the URI of
* the related node, and information about the cause of the exception.
*
* Some of the error codes defined in this class have a corresponding error code
* defined in OMA DM, in these cases the name and numerical value from OMA DM is
* used. Error codes without counterparts in OMA DM were given numbers from a
* different range, starting from 1.
*
* The cause of the exception (if specified) can either be a single
* {@code Throwable} instance, or a list of such instances if several
* problems occurred during the execution of a method. An example for the latter
* is the {@code close} method of {@code DmtSession} that tries to
* close multiple plugins, and has to report the exceptions of all failures.
*
* Each constructor has two variants, one accepts a {@code String} node
* URI, the other accepts a {@code String[]} node path. The former is used
* by the DmtAdmin implementation, the latter by the plugins, who receive the
* node URI as an array of segment names. The constructors are otherwise
* identical.
*
* Getter methods are provided to retrieve the values of the additional
* parameters, and the {@code printStackTrace(PrintWriter)} method is
* extended to print the stack trace of all causing throwables as well.
*
* @version $Id: 4c28c365160136f6d2da2229ab0ba127dea78527 $
*/
public class DmtException extends Exception {
private static final long serialVersionUID = -63006267148118655L;
// ----- Public constants -----//
/**
* The originator's authentication credentials specify a principal with
* insufficient rights to complete the command.
*
* This status code is used as response to device originated sessions if the
* remote management server cannot authorize the device to perform the
* requested operation.
*
* This error code corresponds to the OMA DM response status code 401
* "Unauthorized".
*/
public static final int UNAUTHORIZED = 401;
/**
* The requested target node was not found. No indication is given as to
* whether this is a temporary or permanent condition, unless otherwise
* noted.
*
* This is only used when the requested node name is valid, otherwise the
* more specific error codes {@link #URI_TOO_LONG} or {@link #INVALID_URI}
* are used. This error code corresponds to the OMA DM response status code
* 404 "Not Found".
*/
public static final int NODE_NOT_FOUND = 404;
/**
* The requested command is not allowed on the target node. This includes
* the following situations:
*
*
an interior node operation is requested for a leaf node, or vice
* versa (e.g. trying to retrieve the children of a leaf node)
*
an attempt is made to create a node where the parent is a leaf node
*
an attempt is made to rename or delete the root node of the tree
*
an attempt is made to rename or delete the root node of the session
*
a write operation (other than setting the ACL) is performed in a
* non-atomic write session on a node provided by a plugin that is read-only
* or does not support non-atomic writing
*
a node is copied to its descendant
*
the ACL of the root node is changed not to include Add rights for
* all principals
*
*
* This error code corresponds to the OMA DM response status code 405
* "Command not allowed".
*/
public static final int COMMAND_NOT_ALLOWED = 405;
/**
* The requested command failed because an optional feature required by the
* command is not supported. For example, opening an atomic session might
* return this error code if the DmtAdmin implementation does not support
* transactions. Similarly, accessing the optional node properties (Title,
* Timestamp, Version, Size) might not succeed if either the DmtAdmin
* implementation or the underlying plugin does not support the property.
*
* When getting or setting values for interior nodes (an optional
* optimization feature), a plugin can use this error code to indicate that
* the given interior node does not support values.
*
* This error code corresponds to the OMA DM response status code 406
* "Optional feature not supported".
*/
public static final int FEATURE_NOT_SUPPORTED = 406;
/**
* The requested command failed because the target URI or one of its
* segments is too long for what the recipient is able or willing to
* process, or the target URI contains too many segments. The length and
* segment number limits are implementation dependent, their minimum values
* can be found in the Non Functional Requirements section of the OSGi
* specification.
*
* The {@link Uri#mangle(String)} method provides support for ensuring that
* a URI segment conforms to the length limits set by the implementation.
*
* This error code corresponds to the OMA DM response status code 414
* "URI too long".
*
* @see "OSGi Service Platform, Mobile Specification Release 4"
*/
public static final int URI_TOO_LONG = 414;
/**
* The requested node creation operation failed because the target already
* exists. This can occur if the node is created directly (with one of the
* {@code create...} methods), or indirectly (during a
* {@code copy} operation).
*
* This error code corresponds to the OMA DM response status code 418
* "Already exists".
*/
public static final int NODE_ALREADY_EXISTS = 418;
/**
* The requested command failed because the principal associated with the
* session does not have adequate access control permissions (ACL) on the
* target. This can only appear in case of remote sessions, i.e. if the
* session is associated with an authenticated principal.
*
* This error code corresponds to the OMA DM response status code 425
* "Permission denied".
*/
public static final int PERMISSION_DENIED = 425;
/**
* The recipient encountered an error which prevented it from fulfilling the
* request.
*
* This error code is only used in situations not covered by any of the
* other error codes that a method may use. Some methods specify more
* specific error situations for this code, but it can generally be used for
* any unexpected condition that causes the command to fail.
*
* This error code corresponds to the OMA DM response status code 500
* "Command Failed".
*/
public static final int COMMAND_FAILED = 500;
/**
* An error related to the recipient data store occurred while processing
* the request. This error code may be thrown by any of the methods
* accessing the tree, but whether it is really used depends on the
* implementation, and the data store it uses.
*
* This error code corresponds to the OMA DM response status code 510
* "Data store failure".
*/
public static final int DATA_STORE_FAILURE = 510;
/**
* The rollback command was not completed successfully. The tree might be in
* an inconsistent state after this error.
*
* This error code corresponds to the OMA DM response status code 516
* "Atomic roll back failed".
*/
public static final int ROLLBACK_FAILED = 516;
/**
* A device initiated remote operation failed. This is used when the
* protocol adapter fails to send an alert for any reason.
*
* Alert routing errors (that occur while looking for the proper protocol
* adapter to use) are indicated by {@link #ALERT_NOT_ROUTED}, this code is
* only for errors encountered while sending the routed alert. This error
* code does not correspond to any OMA DM response status code. It should be
* translated to the code 500 "Command Failed" when transferring
* over OMA DM.
*/
public static final int REMOTE_ERROR = 1;
/**
* Operation failed because of meta data restrictions. This covers any
* attempted deviation from the parameters defined by the
* {@code MetaNode} objects of the affected nodes, for example in the
* following situations:
*
*
creating, deleting or renaming a permanent node, or modifying its
* type or value
*
creating an interior node where the meta-node defines it as a leaf,
* or vice versa
*
any operation on a node which does not have the required access type
* (e.g. executing a node that lacks the {@code MetaNode.CMD_EXECUTE}
* access type)
*
any node creation or deletion that would violate the cardinality
* constraints
*
any leaf node value setting that would violate the allowed formats,
* values, mime types, etc.
*
any node creation that would violate the allowed node names
*
*
* This error code can also be used to indicate any other meta data
* violation, even if it cannot be described by the {@code MetaNode}
* class. For example, detecting a multi-node constraint violation while
* committing an atomic session should result in this error.
*
* This error code does not correspond to any OMA DM response status code.
* It should be translated to the code 405 "Command not allowed"
* when transferring over OMA DM.
*/
public static final int METADATA_MISMATCH = 2;
/**
* The requested command failed because the target URI or node name is
* {@code null} or syntactically invalid. This covers the following
* cases:
*
*
the URI or node name ends with the '\' or '/' character
*
the URI is an empty string (only invalid if the method does not
* accept relative URIs)
*
the URI contains the segment "{@code .}" at a position
* other than the beginning of the URI
*
the node name is "{@code ..}" or the URI contains such
* a segment
*
the node name is an empty string or the URI contains an empty segment
*
the node name contains an unescaped '/' character
*
*
* See the {@link Uri#mangle(String)} method for support on escaping invalid
* characters in a URI.
*
* This code is only used if the URI or node name does not match any of the
* criteria for {@link #URI_TOO_LONG}. This error code does not correspond
* to any OMA DM response status code. It should be translated to the code
* 404 "Not Found" when transferring over OMA DM.
*/
public static final int INVALID_URI = 3;
/**
* An error occurred related to concurrent access of nodes. This can happen
* for example if a configuration node was deleted directly through the
* Configuration Admin service, while the node was manipulated via the tree.
*
* This error code does not correspond to any OMA DM response status code.
* It should be translated to the code 500 "Command Failed" when
* transferring over OMA DM.
*/
public static final int CONCURRENT_ACCESS = 4;
/**
* An alert can not be sent from the device to the given principal. This can
* happen if there is no Remote Alert Sender willing to forward the alert to
* the given principal, or if no principal was given and the DmtAdmin did
* not find an appropriate default destination.
*
* This error code does not correspond to any OMA DM response status code.
* It should be translated to the code 500 "Command Failed" when
* transferring over OMA DM.
*/
public static final int ALERT_NOT_ROUTED = 5;
/**
* A transaction-related error occurred in an atomic session. This error is
* caused by one of the following situations:
*
*
an updating method within an atomic session can not be executed
* because the underlying plugin is read-only or does not support atomic
* writing
*
a commit operation at the end of an atomic session failed because
* one of the underlying plugins failed to close
*
* The latter case may leave the tree in an inconsistent state due to the
* lack of a two-phase commit system, see {@link DmtSession#commit} for
* details.
*
* This error code does not correspond to any OMA DM response status code.
* It should be translated to the code 500 "Command Failed" when
* transferring over OMA DM.
*/
public static final int TRANSACTION_ERROR = 6;
/**
* Creation of a session timed out because of another ongoing session. The
* length of time while the DmtAdmin waits for the blocking session(s) to
* finish is implementation dependant.
*
* This error code does not correspond to any OMA DM response status code.
* OMA has several status codes related to timeout, but these are meant to
* be used when a request times out, not if a session can not be
* established. This error code should be translated to the code 500
* "Command Failed" when transferring over OMA DM.
*/
public static final int SESSION_CREATION_TIMEOUT = 7;
// ----- Content fields -----//
/**
* The URI of the node on which the failed DMT operation was issued, or
* {@code null} if the operation was not associated with a node.
*/
private final String uri;
/**
* The error code of the failure, one of the constants defined in this
* class.
*/
private final int code;
/**
* The message associated with the exception, or {@code null} if there
* is no error message.
*/
private final String message;
/**
* The list of originating exceptions, or empty list or {@code null} if
* there are no originating exceptions.
*/
private final Throwable[] causes;
/**
* Determines whether the exception is fatal or not. This is basically a
* two-state severity indicator, with the 'fatal' severity being the more
* serious one.
*/
private final boolean fatal;
// ----- Constructors -----//
/**
* Create an instance of the exception. The {@code uri} and
* {@code message} parameters are optional. No originating exception
* is specified.
*
* @param uri the node on which the failed DMT operation was issued, or
* {@code null} if the operation is not associated with a node
* @param code the error code of the failure
* @param message the message associated with the exception, or
* {@code null} if there is no error message
*/
public DmtException(String uri, int code, String message) {
this(uri, code, message, new Throwable[0], false);
}
/**
* Create an instance of the exception, specifying the cause exception. The
* {@code uri}, {@code message} and {@code cause}
* parameters are optional.
*
* @param uri the node on which the failed DMT operation was issued, or
* {@code null} if the operation is not associated with a node
* @param code the error code of the failure
* @param message the message associated with the exception, or
* {@code null} if there is no error message
* @param cause the originating exception, or {@code null} if there
* is no originating exception
*/
public DmtException(String uri, int code, String message, Throwable cause) {
this(uri, code, message, (cause == null) ? new Throwable[0]
: new Throwable[] { cause }, false);
}
/**
* Create an instance of the exception, specifying the list of cause
* exceptions and whether the exception is a fatal one. This constructor is
* meant to be used by plugins wishing to indicate that a serious error
* occurred which should invalidate the ongoing atomic session. The
* {@code uri}, {@code message} and {@code causes}
* parameters are optional.
*
* If a fatal exception is thrown, no further business methods will be
* called on the originator plugin. In case of atomic sessions, all other
* open plugins will be rolled back automatically, except if the fatal
* exception was thrown during commit.
*
* @param uri the node on which the failed DMT operation was issued, or
* {@code null} if the operation is not associated with a node
* @param code the error code of the failure
* @param message the message associated with the exception, or
* {@code null} if there is no error message
* @param causes the list of originating exceptions, or empty list or
* {@code null} if there are no originating exceptions
* @param fatal whether the exception is fatal
*/
public DmtException(String uri, int code, String message, Vector causes,
boolean fatal) {
this(uri, code, message, (causes == null) ? new Throwable[0]
: (Throwable[]) causes.toArray(new Throwable[causes.size()]),
fatal);
}
private DmtException(String uri, int code, String message,
Throwable[] causes, boolean fatal) {
super((Throwable) null);
this.uri = uri;
this.code = code;
this.message = message;
this.causes = causes;
this.fatal = fatal;
}
/**
* Create an instance of the exception, specifying the target node as an
* array of path segments. This method behaves in exactly the same way as if
* the path was given as a URI string.
*
* @param path the path of the node on which the failed DMT operation was
* issued, or {@code null} if the operation is not associated
* with a node
* @param code the error code of the failure
* @param message the message associated with the exception, or
* {@code null} if there is no error message
* @see #DmtException(String, int, String)
*/
public DmtException(String[] path, int code, String message) {
this(pathToUri(path), code, message);
}
/**
* Create an instance of the exception, specifying the target node as an
* array of path segments, and specifying the cause exception. This method
* behaves in exactly the same way as if the path was given as a URI string.
*
* @param path the path of the node on which the failed DMT operation was
* issued, or {@code null} if the operation is not associated
* with a node
* @param code the error code of the failure
* @param message the message associated with the exception, or
* {@code null} if there is no error message
* @param cause the originating exception, or {@code null} if there
* is no originating exception
* @see #DmtException(String, int, String, Throwable)
*/
public DmtException(String[] path, int code, String message, Throwable cause) {
this(pathToUri(path), code, message, cause);
}
/**
* Create an instance of the exception, specifying the target node as an
* array of path segments, the list of cause exceptions, and whether the
* exception is a fatal one. This method behaves in exactly the same way as
* if the path was given as a URI string.
*
* @param path the path of the node on which the failed DMT operation was
* issued, or {@code null} if the operation is not associated
* with a node
* @param code the error code of the failure
* @param message the message associated with the exception, or
* {@code null} if there is no error message
* @param causes the list of originating exceptions, or empty list or
* {@code null} if there are no originating exceptions
* @param fatal whether the exception is fatal
* @see #DmtException(String, int, String, Vector, boolean)
*/
public DmtException(String[] path, int code, String message, Vector causes,
boolean fatal) {
this(pathToUri(path), code, message, causes, fatal);
}
// ----- Public methods -----//
/**
* Get the node on which the failed DMT operation was issued. Some
* operations like {@code DmtSession.close()} don't require an URI,
* in this case this method returns {@code null}.
*
* @return the URI of the node, or {@code null}
*/
public String getURI() {
return uri;
}
/**
* Get the error code associated with this exception. Most of the error
* codes within this exception correspond to OMA DM error codes.
*
* @return the error code
*/
public int getCode() {
return code;
}
/**
* Get the message associated with this exception. The returned string also
* contains the associated URI (if any) and the exception code. The
* resulting message has the following format (parts in square brackets are
* only included if the field inside them is not {@code null}):
*
*
*
* @return the error message in the format described above
*/
public String getMessage() {
StringBuffer sb = new StringBuffer(getCodeText(code));
if (uri != null)
sb.append(": '").append(uri).append('\'');
if (message != null)
sb.append(": ").append(message);
return sb.toString();
}
/**
* Get the cause of this exception. Returns non-{@code null}, if
* this exception is caused by one or more other exceptions (like a
* {@code NullPointerException} in a DmtPlugin). If there are more
* than one cause exceptions, the first one is returned.
*
* @return the cause of this exception, or {@code null} if no cause
* was given
*/
public Throwable getCause() {
return causes.length == 0 ? null : causes[0];
}
/**
* Get all causes of this exception. Returns the causing exceptions in an
* array. If no cause was specified, an empty array is returned.
*
* @return the list of causes of this exception
*/
public Throwable[] getCauses() {
return (Throwable[]) causes.clone();
}
/**
* Check whether this exception is marked as fatal in the session. Fatal
* exceptions trigger an automatic rollback of atomic sessions.
*
* @return whether the exception is marked as fatal
*/
public boolean isFatal() {
return fatal;
}
/**
* Prints the exception and its backtrace to the specified print stream. Any
* causes that were specified for this exception are also printed, together
* with their backtraces.
*
* @param s {@code PrintStream} to use for output
*/
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
for (int i = 0; i 0 ? " (" + (i+1) + ")" : "") + ": ");
causes[i].printStackTrace(s);
}
}
// ----- Utility methods -----//
/**
* Converts the given path, given as an array of path segments, to a single
* URI string.
*
* @param path the path to convert
* @return the URI string representing the same node as the given path
*/
static String pathToUri(String[] path) {
if (path == null)
return null;
return Uri.toUri(path);
}
/**
* Returns the name of the given error code.
*
* @param code the error code
* @return a string containing the error code name
*/
private static String getCodeText(int code) {
// todo sync codes
switch (code) {
case NODE_NOT_FOUND:
return "NODE_NOT_FOUND";
case COMMAND_NOT_ALLOWED:
return "COMMAND_NOT_ALLOWED";
case FEATURE_NOT_SUPPORTED:
return "FEATURE_NOT_SUPPORTED";
case URI_TOO_LONG:
return "URI_TOO_LONG";
case NODE_ALREADY_EXISTS:
return "NODE_ALREADY_EXISTS";
case PERMISSION_DENIED:
return "PERMISSION_DENIED";
case COMMAND_FAILED:
return "COMMAND_FAILED";
case DATA_STORE_FAILURE:
return "DATA_STORE_FAILURE";
case ROLLBACK_FAILED:
return "ROLLBACK_FAILED";
case REMOTE_ERROR:
return "REMOTE_ERROR";
case METADATA_MISMATCH:
return "METADATA_MISMATCH";
case INVALID_URI:
return "INVALID_URI";
case CONCURRENT_ACCESS:
return "CONCURRENT_ACCESS";
case ALERT_NOT_ROUTED:
return "ALERT_NOT_ROUTED";
case TRANSACTION_ERROR:
return "TRANSACTION_ERROR";
case SESSION_CREATION_TIMEOUT:
return "SESSION_CREATION_TIMEOUT";
default:
return "";
}
}
}
osgi-compendium-4.3.0/src/info/dmtree/security/ 0000755 0001750 0001750 00000000000 11632153414 021362 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/info/dmtree/security/package-info.java 0000644 0001750 0001750 00000002762 11466514064 024567 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Device Management Tree Security Package Version 1.0.
*
*
* This package contains the permission classes used by the Device
* Management API in environments that support the Java 2 security model.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: info.dmtree.security; version="[1.0,1.1)"}
*
* @version $Id: f113975faaa4bcaaadfbdc8855657559c228897a $
*/
package info.dmtree.security;
osgi-compendium-4.3.0/src/info/dmtree/security/AlertPermission.java 0000644 0001750 0001750 00000022247 11466514064 025363 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.security;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
/**
* Indicates the callers authority to send alerts to management servers,
* identified by their principal names.
*
* {@code AlertPermission} has a target string which controls the principal
* names where alerts can be sent. A wildcard is allowed at the end of the
* target string, to allow sending alerts to any principal with a name matching
* the given prefix. The "*" target means that alerts can be sent to
* any destination.
*
* @version $Id: 2cd204e37cfce557d5466f62fe324e30ac807456 $
*/
public class AlertPermission extends Permission {
private static final long serialVersionUID = -3206463101788245739L;
// specifies whether the target string had a wildcard at the end
private final boolean isPrefix;
// the target string without the wildcard (if there was one)
private final String serverId;
/**
* Creates a new {@code AlertPermission} object with its name set to
* the target string. Name must be non-null and non-empty.
*
* @param target the name of a principal, can end with {@code *} to
* match any principal identifier with the given prefix
* @throws NullPointerException if {@code name} is {@code null}
* @throws IllegalArgumentException if {@code name} is empty
*/
public AlertPermission(String target) {
super(target);
if (target == null)
throw new NullPointerException(
"'target' parameter must not be null.");
if (target.equals(""))
throw new IllegalArgumentException(
"'target' parameter must not be empty.");
isPrefix = target.endsWith("*");
if (isPrefix)
serverId = target.substring(0, target.length() - 1);
else
serverId = target;
}
/**
* Creates a new {@code AlertPermission} object using the 'canonical'
* two argument constructor. In this version this class does not define any
* actions, the second argument of this constructor must be "*" so that this
* class can later be extended in a backward compatible way.
*
* @param target the name of the server, can end with {@code *} to
* match any server identifier with the given prefix
* @param actions no actions defined, must be "*" for forward compatibility
* @throws NullPointerException if {@code name} or
* {@code actions} is {@code null}
* @throws IllegalArgumentException if {@code name} is empty or
* {@code actions} is not "*"
*/
public AlertPermission(String target, String actions) {
this(target);
if (actions == null)
throw new NullPointerException(
"'actions' parameter must not be null.");
if (!actions.equals("*"))
throw new IllegalArgumentException(
"'actions' parameter must be \"*\".");
}
/**
* Checks whether the given object is equal to this AlertPermission
* instance. Two AlertPermission instances are equal if they have the same
* target string.
*
* @param obj the object to compare to this AlertPermission instance
* @return {@code true} if the parameter represents the same
* permissions as this instance
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof AlertPermission))
return false;
AlertPermission other = (AlertPermission) obj;
return isPrefix == other.isPrefix && serverId.equals(other.serverId);
}
/**
* Returns the action list (always {@code *} in the current version).
*
* @return the action string "*"
*/
public String getActions() {
return "*";
}
/**
* Returns the hash code for this permission object. If two AlertPermission
* objects are equal according to the {@link #equals} method, then calling
* this method on each of the two AlertPermission objects must produce the
* same integer result.
*
* @return hash code for this permission object
*/
public int hashCode() {
return new Boolean(isPrefix).hashCode() ^ serverId.hashCode();
}
/**
* Checks if this AlertPermission object implies the specified permission.
* Another AlertPermission instance is implied by this permission either if
* the target strings are identical, or if this target can be made identical
* to the other target by replacing a trailing "*" with any
* string.
*
* @param p the permission to check for implication
* @return true if this AlertPermission instance implies the specified
* permission
*/
public boolean implies(Permission p) {
if (!(p instanceof AlertPermission))
return false;
AlertPermission other = (AlertPermission) p;
return impliesServer(other);
}
/**
* Returns a new PermissionCollection object for storing AlertPermission
* objects.
*
* @return the new PermissionCollection
*/
public PermissionCollection newPermissionCollection() {
return new DmtAlertPermissionCollection();
}
/*
* Returns true if the server name parameter of the given AlertPermission is
* implied by the server name of this permission, i.e. this server name is a
* prefix of the other one but ends with a *, or the two server names are
* equal.
*/
boolean impliesServer(AlertPermission p) {
return isPrefix ? p.serverId.startsWith(serverId) : !p.isPrefix
&& p.serverId.equals(serverId);
}
}
/**
* Represents a homogeneous collection of AlertPermission objects.
*/
final class DmtAlertPermissionCollection extends PermissionCollection {
private static final long serialVersionUID = 2288462124510043429L;
private ArrayList perms;
/**
* Create an empty DmtAlertPermissionCollection object.
*/
public DmtAlertPermissionCollection() {
perms = new ArrayList();
}
/**
* Adds a permission to the DmtAlertPermissionCollection.
*
* @param permission the Permission object to add
* @exception IllegalArgumentException if the permission is not a
* AlertPermission
* @exception SecurityException if this DmtAlertPermissionCollection object
* has been marked readonly
*/
public void add(Permission permission) {
if (!(permission instanceof AlertPermission))
throw new IllegalArgumentException(
"Cannot add permission, invalid permission type: "
+ permission);
if (isReadOnly())
throw new SecurityException(
"Cannot add permission, collection is marked read-only.");
// only add new permission if it is not already implied by the
// permissions in the collection
if (!implies(permission)) {
// remove all permissions that are implied by the new one
Iterator i = perms.iterator();
while (i.hasNext())
if (permission.implies((AlertPermission) i.next()))
i.remove();
// no need to synchronize because all adds are done sequentially
// before any implies() calls
perms.add(permission);
}
}
/**
* Check whether this set of permissions implies the permission specified in
* the parameter.
*
* @param permission the Permission object to compare
* @return true if the parameter permission is a proper subset of the
* permissions in the collection, false otherwise
*/
public boolean implies(Permission permission) {
if (!(permission instanceof AlertPermission))
return false;
AlertPermission other = (AlertPermission) permission;
Iterator i = perms.iterator();
while (i.hasNext())
if (((AlertPermission) i.next()).impliesServer(other))
return true;
return false;
}
/**
* Returns an enumeration of all the AlertPermission objects in the
* container. The returned value cannot be {@code null}.
*
* @return an enumeration of all the AlertPermission objects
*/
public Enumeration elements() {
// Convert Iterator into Enumeration
return Collections.enumeration(perms);
}
}
osgi-compendium-4.3.0/src/info/dmtree/security/packageinfo 0000644 0001750 0001750 00000000014 11405717676 023565 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/info/dmtree/security/DmtPrincipalPermission.java 0000644 0001750 0001750 00000023037 11466514064 026700 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.security;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
/**
* Indicates the callers authority to create DMT sessions on behalf of a remote
* management server. Only protocol adapters communicating with management
* servers should be granted this permission.
*
* {@code DmtPrincipalPermission} has a target string which controls the
* name of the principal on whose behalf the protocol adapter can act. A
* wildcard is allowed at the end of the target string, to allow using any
* principal name with the given prefix. The "*" target means the
* adapter can create a session in the name of any principal.
*
* @version $Id: f2894cf7a413e4308702b8f943b70556f6697d77 $
*/
public class DmtPrincipalPermission extends Permission {
private static final long serialVersionUID = 6388752177325038332L;
// specifies whether the target string had a wildcard at the end
private final boolean isPrefix;
// the target string without the wildcard (if there was one)
private final String principal;
/**
* Creates a new {@code DmtPrincipalPermission} object with its name
* set to the target string. Name must be non-null and non-empty.
*
* @param target the name of the principal, can end with {@code *} to
* match any principal with the given prefix
* @throws NullPointerException if {@code name} is {@code null}
* @throws IllegalArgumentException if {@code name} is empty
*/
public DmtPrincipalPermission(String target) {
super(target);
if (target == null)
throw new NullPointerException(
"'target' parameter must not be null.");
if (target.equals(""))
throw new IllegalArgumentException(
"'target' parameter must not be empty.");
isPrefix = target.endsWith("*");
if (isPrefix)
principal = target.substring(0, target.length() - 1);
else
principal = target;
}
/**
* Creates a new {@code DmtPrincipalPermission} object using the
* 'canonical' two argument constructor. In this version this class does not
* define any actions, the second argument of this constructor must be "*"
* so that this class can later be extended in a backward compatible way.
*
* @param target the name of the principal, can end with {@code *} to
* match any principal with the given prefix
* @param actions no actions defined, must be "*" for forward compatibility
* @throws NullPointerException if {@code name} or
* {@code actions} is {@code null}
* @throws IllegalArgumentException if {@code name} is empty or
* {@code actions} is not "*"
*/
public DmtPrincipalPermission(String target, String actions) {
this(target);
if (actions == null)
throw new NullPointerException(
"'actions' parameter must not be null.");
if (!actions.equals("*"))
throw new IllegalArgumentException(
"'actions' parameter must be \"*\".");
}
/**
* Checks whether the given object is equal to this DmtPrincipalPermission
* instance. Two DmtPrincipalPermission instances are equal if they have the
* same target string.
*
* @param obj the object to compare to this DmtPrincipalPermission instance
* @return {@code true} if the parameter represents the same
* permissions as this instance
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof DmtPrincipalPermission))
return false;
DmtPrincipalPermission other = (DmtPrincipalPermission) obj;
return isPrefix == other.isPrefix && principal.equals(other.principal);
}
/**
* Returns the action list (always {@code *} in the current version).
*
* @return the action string "*"
*/
public String getActions() {
return "*";
}
/**
* Returns the hash code for this permission object. If two
* DmtPrincipalPermission objects are equal according to the {@link #equals}
* method, then calling this method on each of the two
* DmtPrincipalPermission objects must produce the same integer result.
*
* @return hash code for this permission object
*/
public int hashCode() {
return new Boolean(isPrefix).hashCode() ^ principal.hashCode();
}
/**
* Checks if this DmtPrincipalPermission object implies the specified
* permission. Another DmtPrincipalPermission instance is implied by this
* permission either if the target strings are identical, or if this target
* can be made identical to the other target by replacing a trailing
* "*" with any string.
*
* @param p the permission to check for implication
* @return true if this DmtPrincipalPermission instance implies the
* specified permission
*/
public boolean implies(Permission p) {
if (!(p instanceof DmtPrincipalPermission))
return false;
DmtPrincipalPermission other = (DmtPrincipalPermission) p;
return impliesPrincipal(other);
}
/**
* Returns a new PermissionCollection object for storing
* DmtPrincipalPermission objects.
*
* @return the new PermissionCollection
*/
public PermissionCollection newPermissionCollection() {
return new DmtPrincipalPermissionCollection();
}
/*
* Returns true if the principal parameter of the given
* DmtPrincipalPermission is implied by the principal of this permission,
* i.e. this principal is a prefix of the other principal but ends with a *,
* or the two principal strings are equal.
*/
boolean impliesPrincipal(DmtPrincipalPermission p) {
return isPrefix ? p.principal.startsWith(principal) : !p.isPrefix
&& p.principal.equals(principal);
}
}
/**
* Represents a homogeneous collection of DmtPrincipalPermission objects.
*/
final class DmtPrincipalPermissionCollection extends PermissionCollection {
private static final long serialVersionUID = -6692103535775802684L;
private ArrayList perms;
/**
* Create an empty DmtPrincipalPermissionCollection object.
*/
public DmtPrincipalPermissionCollection() {
perms = new ArrayList();
}
/**
* Adds a permission to the DmtPrincipalPermissionCollection.
*
* @param permission the Permission object to add
* @exception IllegalArgumentException if the permission is not a
* DmtPrincipalPermission
* @exception SecurityException if this DmtPrincipalPermissionCollection
* object has been marked readonly
*/
public void add(Permission permission) {
if (!(permission instanceof DmtPrincipalPermission))
throw new IllegalArgumentException(
"Cannot add permission, invalid permission type: "
+ permission);
if (isReadOnly())
throw new SecurityException(
"Cannot add permission, collection is marked read-only.");
// only add new permission if it is not already implied by the
// permissions in the collection
if (!implies(permission)) {
// remove all permissions that are implied by the new one
Iterator i = perms.iterator();
while (i.hasNext())
if (permission.implies((DmtPrincipalPermission) i.next()))
i.remove();
// no need to synchronize because all adds are done sequentially
// before any implies() calls
perms.add(permission);
}
}
/**
* Check whether this set of permissions implies the permission specified in
* the parameter.
*
* @param permission the Permission object to compare
* @return true if the parameter permission is a proper subset of the
* permissions in the collection, false otherwise
*/
public boolean implies(Permission permission) {
if (!(permission instanceof DmtPrincipalPermission))
return false;
DmtPrincipalPermission other = (DmtPrincipalPermission) permission;
Iterator i = perms.iterator();
while (i.hasNext())
if (((DmtPrincipalPermission) i.next()).impliesPrincipal(other))
return true;
return false;
}
/**
* Returns an enumeration of all the DmtPrincipalPermission objects in the
* container. The returned value cannot be {@code null}.
*
* @return an enumeration of all the DmtPrincipalPermission objects
*/
public Enumeration elements() {
// Convert Iterator into Enumeration
return Collections.enumeration(perms);
}
}
osgi-compendium-4.3.0/src/info/dmtree/security/DmtPermission.java 0000644 0001750 0001750 00000040445 11466514064 025040 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.security;
import info.dmtree.Acl;
import info.dmtree.Uri;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.StringTokenizer;
/**
* Controls access to management objects in the Device Management Tree (DMT). It
* is intended to control local access to the DMT. DmtPermission target string
* identifies the management object URI and the action field lists the OMA DM
* commands that are permitted on the management object. Example:
*
*
*
* This means that owner of this permission can execute Add, Replace and Get
* commands on the ./OSGi/bundles management object. It is possible to use
* wildcards in both the target and the actions field. Wildcard in the target
* field means that the owner of the permission can access children nodes of the
* target node. Example:
*
*
* DmtPermission("./OSGi/bundles/*", "Get");
*
*
* This means that owner of this permission has Get access on every child node
* of ./OSGi/bundles. The asterix does not necessarily have to follow a '/'
* character. For example the {@code "./OSGi/a*"} target matches
* the {@code ./OSGi/applications} subtree.
*
* If wildcard is present in the actions field, all legal OMA DM commands are
* allowed on the designated nodes(s) by the owner of the permission. Action
* names are interpreted case-insensitively, but the canonical action string
* returned by {@link #getActions} uses the forms defined by the action
* constants.
*
* @version $Id: b0e2d35af55ac4ed117b4988b2c3a3f57081ab6d $
*/
public class DmtPermission extends Permission {
private static final long serialVersionUID = -1910969921419407809L;
/**
* Holders of DmtPermission with the Add action present can create new nodes
* in the DMT, that is they are authorized to execute the
* createInteriorNode() and createLeafNode() methods of the DmtSession. This
* action is also required for the copy() command, which needs to perform
* node creation operations (among others).
*/
public static final String ADD = "Add";
/**
* Holders of DmtPermission with the Delete action present can delete nodes
* from the DMT, that is they are authorized to execute the deleteNode()
* method of the DmtSession.
*/
public static final String DELETE = "Delete";
/**
* Holders of DmtPermission with the Exec action present can execute nodes
* in the DMT, that is they are authorized to call the execute() method of
* the DmtSession.
*/
public static final String EXEC = "Exec";
/**
* Holders of DmtPermission with the Get action present can query DMT node
* value or properties, that is they are authorized to execute the
* isLeafNode(), getNodeAcl(), getEffectiveNodeAcl(), getMetaNode(),
* getNodeValue(), getChildNodeNames(), getNodeTitle(), getNodeVersion(),
* getNodeTimeStamp(), getNodeSize() and getNodeType() methods of the
* DmtSession. This action is also required for the copy() command, which
* needs to perform node query operations (among others).
*/
public static final String GET = "Get";
/**
* Holders of DmtPermission with the Replace action present can update DMT
* node value or properties, that is they are authorized to execute the
* setNodeAcl(), setNodeTitle(), setNodeValue(), setNodeType() and
* renameNode() methods of the DmtSession. This action is also be required
* for the copy() command if the original node had a title property (which
* must be set in the new node).
*/
public static final String REPLACE = "Replace";
// does this permission have a wildcard at the end?
private final boolean prefixPath;
// the name without the wildcard on the end
private final String path;
// the actions mask
private final int mask;
// the canonical action string (redundant)
private final String actions;
/**
* Creates a new DmtPermission object for the specified DMT URI with the
* specified actions. The given URI can be:
*
*
{@code "*"}, which matches all valid
* (see {@link Uri#isValidUri}) absolute URIs;
*
the prefix of an absolute URI followed by the {@code *}
* character (for example {@code "./OSGi/L*"}), which matches all valid
* absolute URIs beginning with the given prefix;
*
a valid absolute URI, which matches itself.
*
*
* Since the {@code *} character is itself a valid URI character, it
* can appear as the last character of a valid absolute URI. To distinguish
* this case from using {@code *} as a wildcard, the {@code *}
* character at the end of the URI must be escaped with the {@code \}
* charater. For example the URI {@code "./a*"} matches
* {@code "./a"}, {@code "./aa"}, {@code "./a/b"} etc. while
* {@code "./a\*"} matches {@code "./a*"} only.
*
* The actions string must either be "*" to allow all actions, or it must
* contain a non-empty subset of the valid actions, defined as constants in
* this class.
*
* @param dmtUri URI of the management object (or subtree)
* @param actions OMA DM actions allowed
* @throws NullPointerException if any of the parameters are
* {@code null}
* @throws IllegalArgumentException if any of the parameters are invalid
*/
public DmtPermission(String dmtUri, String actions) {
super(dmtUri);
mask = getMask(actions);
this.actions = canonicalActions(mask);
if (dmtUri == null)
throw new NullPointerException("'dmtUri' parameter must not be " +
"null.");
prefixPath = dmtUri.endsWith("*") && !dmtUri.endsWith("\\*");
if(prefixPath) {
dmtUri = dmtUri.substring(0, dmtUri.length() - 1);
// the single "*" as dmtUri is the only valid non-absolute URI param
if(dmtUri.length() == 0) {
path = "";
return;
}
}
// if URI ends with "/*", remove it before the validity check
if(prefixPath && dmtUri.endsWith("/") && !dmtUri.endsWith("\\/"))
checkUri(dmtUri.substring(0, dmtUri.length() - 1));
else
checkUri(dmtUri);
// canonicalize URI: remove escapes from non-special characters
StringBuffer sb = new StringBuffer(dmtUri);
int i = 0;
while(i < sb.length()) { // length can decrease during the loop!
if(sb.charAt(i) == '\\') {
// there must be a next character after a '\' in a valid URI
char nextCh = sb.charAt(i+1);
if(nextCh != '/' && nextCh != '\\')
sb.deleteCharAt(i); // remove the extra '\'
else
i++;
}
i++;
}
path = sb.toString();
}
private void checkUri(String dmtUri) throws IllegalArgumentException {
if(!Uri.isValidUri(dmtUri))
throw new IllegalArgumentException("'dmtUri' parameter does not " +
"contain a valid URI.");
if(!Uri.isAbsoluteUri(dmtUri))
throw new IllegalArgumentException("'dmtUri' parameter does not " +
"contain an absolute URI.");
}
/**
* Checks whether the given object is equal to this DmtPermission instance.
* Two DmtPermission instances are equal if they have the same target string
* and the same action mask. The "*" action mask is considered equal to a
* mask containing all actions.
*
* @param obj the object to compare to this DmtPermission instance
* @return {@code true} if the parameter represents the same
* permissions as this instance
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof DmtPermission))
return false;
DmtPermission other = (DmtPermission) obj;
return mask == other.mask && prefixPath == other.prefixPath
&& path.equals(other.path);
}
/**
* Returns the String representation of the action list. The allowed actions
* are listed in the following order: Add, Delete, Exec, Get, Replace. The
* wildcard character is not used in the returned string, even if the class
* was created using the "*" wildcard.
*
* @return canonical action list for this permission object
*/
public String getActions() {
return actions;
}
/**
* Returns the hash code for this permission object. If two DmtPermission
* objects are equal according to the {@link #equals} method, then calling
* this method on each of the two DmtPermission objects must produce the
* same integer result.
*
* @return hash code for this permission object
*/
public int hashCode() {
return new Integer(mask).hashCode()
^ new Boolean(prefixPath).hashCode() ^ path.hashCode();
}
/**
* Checks if this DmtPermission object "implies" the specified
* permission. This method returns {@code false} if and only if at
* least one of the following conditions are fulfilled for the specified
* permission:
*
*
it is not a DmtPermission
*
its set of actions contains an action not allowed by this permission
*
the set of nodes defined by its path contains a node not defined by
* the path of this permission
*
*
* @param p the permission to check for implication
* @return true if this DmtPermission instance implies the specified
* permission
*/
public boolean implies(Permission p) {
if (!(p instanceof DmtPermission))
return false;
DmtPermission other = (DmtPermission) p;
if ((mask & other.mask) != other.mask)
return false;
return impliesPath(other);
}
/**
* Returns a new PermissionCollection object for storing DmtPermission
* objects.
*
* @return the new PermissionCollection
*/
public PermissionCollection newPermissionCollection() {
return new DmtPermissionCollection();
}
// parses the given action string, and returns the corresponding action mask
private static int getMask(String actions) {
int mask = 0;
if (actions == null)
throw new NullPointerException(
"'actions' parameter cannot be null.");
if (actions.equals("*"))
return Acl.ALL_PERMISSION;
// empty tokens (swallowed by StringTokenizer) are not considered errors
StringTokenizer st = new StringTokenizer(actions, ",");
while (st.hasMoreTokens()) {
String action = st.nextToken().trim();
if (action.equalsIgnoreCase(GET)) {
mask |= Acl.GET;
} else if (action.equalsIgnoreCase(ADD)) {
mask |= Acl.ADD;
} else if (action.equalsIgnoreCase(REPLACE)) {
mask |= Acl.REPLACE;
} else if (action.equalsIgnoreCase(DELETE)) {
mask |= Acl.DELETE;
} else if (action.equalsIgnoreCase(EXEC)) {
mask |= Acl.EXEC;
} else
throw new IllegalArgumentException("Invalid action '" + action
+ "'");
}
if (mask == 0)
throw new IllegalArgumentException("Action mask cannot be empty.");
return mask;
}
// generates the canonical string representation of the action list
private static String canonicalActions(int mask) {
StringBuffer sb = new StringBuffer();
addAction(sb, mask, Acl.ADD, ADD);
addAction(sb, mask, Acl.DELETE, DELETE);
addAction(sb, mask, Acl.EXEC, EXEC);
addAction(sb, mask, Acl.GET, GET);
addAction(sb, mask, Acl.REPLACE, REPLACE);
return sb.toString();
}
// if 'flag' appears in 'mask', appends the 'action' string to the contents
// of 'sb', separated by a comma if needed
private static void addAction(StringBuffer sb, int mask, int flag,
String action) {
if ((mask & flag) != 0) {
if (sb.length() > 0)
sb.append(',');
sb.append(action);
}
}
// used by DmtPermissionCollection to retrieve the action mask
int getMask() {
return mask;
}
// returns true if the path parameter of the given DmtPermission is
// implied by the path of this permission, i.e. this path is a prefix of the
// other path, but ends with a *, or the two path strings are equal
boolean impliesPath(DmtPermission p) {
return prefixPath ? p.path.startsWith(path) : !p.prefixPath
&& p.path.equals(path);
}
}
/**
* Represents a homogeneous collection of DmtPermission objects.
*/
final class DmtPermissionCollection extends PermissionCollection {
private static final long serialVersionUID = -4172481774562012941L;
// OPTIMIZE keep a special flag for permissions of "*" path
private ArrayList perms;
/**
* Create an empty DmtPermissionCollection object.
*/
public DmtPermissionCollection() {
perms = new ArrayList();
}
/**
* Adds a permission to the DmtPermissionCollection.
*
* @param permission the Permission object to add
* @exception IllegalArgumentException if the permission is not a
* DmtPermission
* @exception SecurityException if this DmtPermissionCollection object has
* been marked readonly
*/
public void add(Permission permission) {
if (!(permission instanceof DmtPermission))
throw new IllegalArgumentException(
"Cannot add permission, invalid permission type: "
+ permission);
if (isReadOnly())
throw new SecurityException(
"Cannot add permission, collection is marked read-only.");
// No need to synchronize because all adds are done sequentially
// before any implies() calls
perms.add(permission);
}
/**
* Check whether this set of permissions implies the permission specified in
* the parameter.
*
* @param permission the Permission object to compare
* @return true if the parameter permission is a proper subset of the
* permissions in the collection, false otherwise
*/
public boolean implies(Permission permission) {
if (!(permission instanceof DmtPermission))
return false;
DmtPermission other = (DmtPermission) permission;
int required = other.getMask();
int available = 0;
int needed = required;
Iterator i = perms.iterator();
while (i.hasNext()) {
DmtPermission p = (DmtPermission) i.next();
if (((needed & p.getMask()) != 0) && p.impliesPath(other)) {
available |= p.getMask();
if ((available & required) == required)
return true;
needed = (required ^ available);
}
}
return false;
}
/**
* Returns an enumeration of all the DmtPermission objects in the container.
* The returned value cannot be {@code null}.
*
* @return an enumeration of all the DmtPermission objects
*/
public Enumeration elements() {
// Convert Iterator into Enumeration
return Collections.enumeration(perms);
}
}
osgi-compendium-4.3.0/src/info/dmtree/notification/ 0000755 0001750 0001750 00000000000 11632153414 022201 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/info/dmtree/notification/package-info.java 0000644 0001750 0001750 00000003143 11466514064 025400 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Device Management Tree Notification Package Version 1.0.
*
*
* This package contains the public API of the Notification service. This service
* enables the sending of asynchronous notifications to management servers.
* Permission classes are provided by the {@code info.dmtree.security} package.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: info.dmtree.notification; version="[1.0,1.1)"}
*
* @version $Id: f5805c2959795df8d5c39a3bd0a5634a424f9b47 $
*/
package info.dmtree.notification;
osgi-compendium-4.3.0/src/info/dmtree/notification/AlertItem.java 0000644 0001750 0001750 00000014730 11466514064 024746 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.notification;
import info.dmtree.DmtData;
import info.dmtree.Uri;
/**
* Immutable data structure carried in an alert (client initiated notification).
* The {@code AlertItem} describes details of various notifications that
* can be sent by the client, for example as alerts in the OMA DM protocol. The
* use cases include the client sending a session request to the server (alert
* 1201), the client notifying the server of completion of a software update
* operation (alert 1226) or sending back results in response to an asynchronous
* EXEC command.
*
* The data syntax and semantics varies widely between various alerts, so does
* the optionality of particular parameters of an alert item. If an item, such
* as source or type, is not defined, the corresponding getter method returns
* {@code null}. For example, for alert 1201 (client-initiated session) all
* elements will be {@code null}.
*
* The syntax used in {@code AlertItem} class corresponds to the OMA DM
* alert format. {@link NotificationService} implementations on other management
* protocols should map these constructs to the underlying protocol.
*
* @version $Id: 8ed4f9c425e774840eaaae00e924798be8b997f2 $
*/
public class AlertItem {
private final String source;
private final String type;
private final String mark;
private final DmtData data;
/**
* Create an instance of the alert item. The constructor takes all possible
* data entries as parameters. Any of these parameters can be
* {@code null}. The semantics of the parameters may be refined by
* the definition of a specific alert, identified by its alert code (see
* {@link NotificationService#sendNotification}). In case of Generic Alerts
* for example (code 1226), the {@code mark} parameter contains a
* severity string.
*
* @param source the URI of the node which is the source of the alert item
* @param type a MIME type or a URN that identifies the type of the data in
* the alert item
* @param data a {@code DmtData} object that contains the format and
* value of the data in the alert item
* @param mark the mark parameter of the alert item
*/
public AlertItem(String source, String type, String mark, DmtData data) {
this.source = source;
this.type = type;
this.mark = mark;
this.data = data;
}
/**
* Create an instance of the alert item, specifying the source node URI as
* an array of path segments. The constructor takes all possible data
* entries as parameters. Any of these parameters can be {@code null}.
* The semantics of the parameters may be refined by the definition of a
* specific alert, identified by its alert code (see
* {@link NotificationService#sendNotification}). In case of Generic Alerts
* for example (code 1226), the {@code mark} parameter contains a
* severity string.
*
* @param source the path of the node which is the source of the alert item
* @param type a MIME type or a URN that identifies the type of the data in
* the alert item
* @param data a {@code DmtData} object that contains the format and
* value of the data in the alert item
* @param mark the mark parameter of the alert item
*/
public AlertItem(String[] source, String type, String mark, DmtData data) {
if ((null == source)) {
this.source = null;
} else {
this.source = Uri.toUri(source);
}
this.type = type;
this.mark = mark;
this.data = data;
}
/**
* Get the node which is the source of the alert. There might be no source
* associated with the alert item.
*
* @return the URI of the node which is the source of this alert, or
* {@code null} if there is no source
*/
public String getSource() {
return source;
}
/**
* Get the type associated with the alert item. The type string is a MIME
* type or a URN that identifies the type of the data in the alert item
* (returned by {@link #getData}). There might be no type associated with
* the alert item.
*
* @return the type type associated with the alert item, or
* {@code null} if there is no type
*/
public String getType() {
return type;
}
/**
* Get the mark parameter associated with the alert item. The interpretation
* of the mark parameter depends on the alert being sent, as identified by
* the alert code in {@link NotificationService#sendNotification}. There
* might be no mark associated with the alert item.
*
* @return the mark associated with the alert item, or {@code null}
* if there is no mark
*/
public String getMark() {
return mark;
}
/**
* Get the data associated with the alert item. The returned
* {@code DmtData} object contains the format and the value of the
* data in the alert item. There might be no data associated with the alert
* item.
*
* @return the data associated with the alert item, or {@code null}
* if there is no data
*/
public DmtData getData() {
return data;
}
/**
* Returns the string representation of this alert item. The returned string
* includes all parameters of the alert item, and has the following format:
*
*
* AlertItem(<source>, <type>, <mark>, <data>)
*
*
* The last parameter is the string representation of the data value. The
* format of the data is not explicitly included.
*
* @return the string representation of this alert item
*/
public String toString() {
return "AlertItem(" + source + ", " + type + ", " + mark + ", " + data
+ ")";
}
}
osgi-compendium-4.3.0/src/info/dmtree/notification/NotificationService.java 0000644 0001750 0001750 00000011732 11466514064 027026 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.notification;
import info.dmtree.DmtException;
import info.dmtree.DmtSession;
/**
* NotificationService enables sending aynchronous notifications to a management
* server. The implementation of {@code NotificationService} should
* register itself in the OSGi service registry as a service.
*
* @version $Id: b7acf86bcc10a1d479456ba684e01ba8b18166cf $
*/
public interface NotificationService {
/**
* Sends a notification to a named principal. It is the responsibility of
* the {@code NotificationService} to route the notification to the
* given principal using the registered
* {@link info.dmtree.notification.spi.RemoteAlertSender} services.
*
* In remotely initiated sessions the principal name identifies the remote
* server that created the session, this can be obtained using the session's
* {@link DmtSession#getPrincipal getPrincipal} call.
*
* The principal name may be omitted if the client does not know the
* principal name. Even in this case the routing might be possible if the
* Notification Service finds an appropriate default destination (for
* example if it is only connected to one protocol adapter, which is only
* connected to one management server).
*
* Since sending the notification and receiving acknowledgment for it is
* potentially a very time-consuming operation, notifications are sent
* asynchronously. This method should attempt to ensure that the
* notification can be sent successfully, and should throw an exception if
* it detects any problems. If the method returns without error, the
* notification is accepted for sending and the implementation must make a
* best-effort attempt to deliver it.
*
* In case the notification is an asynchronous response to a previous
* {@link DmtSession#execute(String, String, String) execute} command, a
* correlation identifier can be specified to provide the association
* between the execute and the notification.
*
* In order to send a notification using this method, the caller must have
* an {@code AlertPermission} with a target string matching the
* specified principal name. If the {@code principal} parameter is
* {@code null} (the principal name is not known), the target of the
* {@code AlertPermission} must be "*".
*
* When this method is called with all its parameters {@code null} or 0
* (except {@code principal}), it should send a protocol
* specific default notification to initiate a management session. For
* example, in case of OMA DM this is alert 1201 "Client Initiated Session".
* The {@code principal} parameter can be used to determine the
* recipient of the session initiation request.
*
* @param principal the principal name which is the recipient of this
* notification, can be {@code null}
* @param code the alert code, can be 0 if not needed
* @param correlator optional field that contains the correlation identifier
* of an associated exec command, can be {@code null} if not
* needed
* @param items the data of the alert items carried in this alert, can be
* {@code null} or empty if not needed
* @throws DmtException with the following possible error codes:
*
*
{@code UNAUTHORIZED} when the remote server rejected
* the request due to insufficient authorization
*
{@code ALERT_NOT_ROUTED} when the alert can not be
* routed to the given principal
*
{@code REMOTE_ERROR} in case of communication
* problems between the device and the destination
*
{@code COMMAND_FAILED} for unspecified errors
* encountered while attempting to complete the command
*
{@code FEATURE_NOT_SUPPORTED} if the underlying
* management protocol doesn't support asynchronous notifications
*
* @throws SecurityException if the caller does not have the required
* {@code AlertPermission} with a target matching the
* {@code principal} parameter, as described above
*/
void sendNotification(String principal, int code, String correlator,
AlertItem[] items) throws DmtException;
}
osgi-compendium-4.3.0/src/info/dmtree/notification/packageinfo 0000644 0001750 0001750 00000000014 11405717676 024404 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/info/dmtree/notification/spi/ 0000755 0001750 0001750 00000000000 11632153414 022774 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/info/dmtree/notification/spi/package-info.java 0000644 0001750 0001750 00000003326 11466514064 026176 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Device Management Tree Notification SPI Package Version 1.0.
*
*
* This package contains the SPI (Service Provider Interface) of the Notification
* service. These interfaces are implemented by Protocol Adapters capable of
* delivering notifications to management servers on a specific protocol. Users of
* the {@code NotificationService} interface do not interact directly with this
* package.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: info.dmtree.notification.spi; version="[1.0,1.1)"}
*
* @version $Id: 2c273b00d322bca78476155dffb03e0e6344ea9b $
*/
package info.dmtree.notification.spi;
osgi-compendium-4.3.0/src/info/dmtree/notification/spi/packageinfo 0000644 0001750 0001750 00000000014 11405717676 025177 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/info/dmtree/notification/spi/RemoteAlertSender.java 0000644 0001750 0001750 00000010142 11466514064 027230 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.notification.spi;
import info.dmtree.notification.AlertItem;
/**
* The RemoteAlertSender can be used to send notifications to (remote) entities
* identified by principal names. This service is provided by Protocol Adapters,
* and is used by the {@link info.dmtree.notification.NotificationService} when
* sending alerts. Implementations of this interface have to be able to connect
* and send alerts to one or more management servers in a protocol specific way.
*
* The properties of the service registration should specify a list of
* destinations (principals) where the service is capable of sending alerts.
* This can be done by providing a {@code String} array of principal names
* in the {@code principals} registration property. If this property is not
* registered, the service will be treated as the default sender. The default
* alert sender is only used when a more specific alert sender cannot be found.
*
* The {@code principals} registration property is used when the
* {@link info.dmtree.notification.NotificationService#sendNotification} method
* is called, to find the proper {@code RemoteAlertSender} for the given
* destination. If the caller does not specify a principal, the alert is only
* sent if the Notification Sender finds a default alert sender, or if the
* choice is unambiguous for some other reason (for example if only one alert
* sender is registered).
*
* @version $Id: 885f0d730d8f9ff88b872f95dee8a91daf97e2d4 $
*/
public interface RemoteAlertSender {
/**
* Sends an alert to a server identified by its principal name. In case the
* alert is sent in response to a previous
* {@link info.dmtree.DmtSession#execute(String, String, String) execute}
* command, a correlation identifier can be specified to provide the
* association between the execute and the alert.
*
* The {@code principal} parameter specifies which server the alert
* should be sent to. This parameter can be {@code null} if the
* client does not know the name of the destination. The alert should still
* be delivered if possible; for example if the alert sender is only
* connected to one destination.
*
* Any exception thrown on this method will be propagated to the original
* sender of the event, wrapped in a {@code DmtException} with the
* code {@code REMOTE_ERROR}.
*
* Since sending the alert and receiving acknowledgment for it is
* potentially a very time-consuming operation, alerts are sent
* asynchronously. This method should attempt to ensure that the alert can
* be sent successfully, and should throw an exception if it detects any
* problems. If the method returns without error, the alert is accepted for
* sending and the implementation must make a best-effort attempt to deliver
* it.
*
* @param principal the name identifying the server where the alert should
* be sent, can be {@code null}
* @param code the alert code, can be 0 if not needed
* @param correlator the correlation identifier of an associated EXEC
* command, or {@code null} if there is no associated EXEC
* @param items the data of the alert items carried in this alert, can be
* empty or {@code null} if no alert items are needed
* @throws Exception if the alert can not be sent to the server
*/
void sendAlert(String principal, int code, String correlator,
AlertItem[] items) throws Exception;
}
osgi-compendium-4.3.0/src/info/dmtree/Acl.java 0000644 0001750 0001750 00000054770 11466514064 021101 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;
/**
* {@code Acl} is an immutable class representing structured access to DMT
* ACLs. Under OMA DM the ACLs are defined as strings with an internal syntax.
*
* The methods of this class taking a principal as parameter accept remote
* server IDs (as passed to {@link DmtAdmin#getSession(String, String, int)
* DmtAdmin.getSession}), as well as " {@code *} " indicating any
* principal.
*
* The syntax for valid remote server IDs:
* <server-identifier> ::= All printable characters except
* {@code '='}, {@code '&'}, {@code '*'}, {@code '+'} or white-space
* characters.
*
* @version $Id: 13eb07de6924756e573ff2eb72db6b66e4e53cc7 $
*/
public final class Acl {
// ----- Public constants -----//
/**
* Principals holding this permission can issue GET command on the node
* having this ACL.
*/
public static final int GET = 1;
/**
* Principals holding this permission can issue ADD commands on the node
* having this ACL.
*/
public static final int ADD = 2;
/**
* Principals holding this permission can issue REPLACE commands on the node
* having this ACL.
*/
public static final int REPLACE = 4;
/**
* Principals holding this permission can issue DELETE commands on the node
* having this ACL.
*/
public static final int DELETE = 8;
/**
* Principals holding this permission can issue EXEC commands on the node
* having this ACL.
*/
public static final int EXEC = 16;
/**
* Principals holding this permission can issue any command on the node
* having this ACL. This permission is the logical OR of {@link #ADD},
* {@link #DELETE}, {@link #EXEC}, {@link #GET} and {@link #REPLACE}
* permissions.
*/
public static final int ALL_PERMISSION = ADD | DELETE | EXEC | GET
| REPLACE;
// ----- Private constants -----//
private static final int[] PERMISSION_CODES = new int[] { ADD, DELETE,
EXEC, GET, REPLACE };
private static final String[] PERMISSION_NAMES = new String[] { "Add",
"Delete", "Exec", "Get", "Replace" };
private static final String ALL_PRINCIPALS = "*";
// ----- Private fields -----//
// the implementation takes advantage of this being a sorted map
private final TreeMap principalPermissions;
private final int globalPermissions;
// ----- Public constructors -----//
/**
* Create an instance of the ACL from its canonic string representation.
*
* @param acl The string representation of the ACL as defined in OMA DM. If
* {@code null} or empty then it represents an empty list of
* principals with no permissions.
* @throws IllegalArgumentException if acl is not a valid OMA DM ACL string
*/
public Acl(String acl) {
if (acl == null || acl.equals("")) { // empty permission set
principalPermissions = new TreeMap();
globalPermissions = 0;
return;
}
TreeMap tempPrincipalPermissions = new TreeMap();
int tempGlobalPermissions = 0;
String[] aclEntries = split(acl, '&', -1);
for (int i = 0; i < aclEntries.length; i++) {
if (aclEntries[i].length() == 0)
throw new IllegalArgumentException(
"Invalid ACL string: empty ACL entry.");
String[] entryParts = split(aclEntries[i], '=', 2);
if (entryParts.length == 1)
throw new IllegalArgumentException(
"Invalid ACL string: no '=' in ACL entry.");
if (entryParts[1].length() == 0)
throw new IllegalArgumentException(
"Invalid ACL string: no server identifiers in ACL entry.");
int command = parseCommand(entryParts[0]);
String[] serverIds = split(entryParts[1], '+', -1);
for (int j = 0; j < serverIds.length; j++) {
if (serverIds[j].length() == 0)
throw new IllegalArgumentException(
"Invalid ACL string: empty server identifier.");
if (serverIds[j].equals(ALL_PRINCIPALS))
tempGlobalPermissions |= command;
else {
checkServerId(serverIds[j], "Invalid ACL string: "
+ "server ID contains illegal character");
Integer n = (Integer) tempPrincipalPermissions
.get(serverIds[j]);
int oldPermission = (n != null) ? n.intValue() : 0;
tempPrincipalPermissions.put(serverIds[j], new Integer(
oldPermission | command));
}
}
}
principalPermissions = tempPrincipalPermissions;
globalPermissions = tempGlobalPermissions;
}
/**
* Creates an instance with a specified list of principals and the
* permissions they hold. The two arrays run in parallel, that is
* {@code principals[i]} will hold {@code permissions[i]} in
* the ACL.
*
* A principal name may not appear multiple times in the 'principals'
* argument. If the "*" principal appears in the array, the
* corresponding permissions will be granted to all principals (regardless
* of whether they appear in the array or not).
*
* @param principals The array of principals
* @param permissions The array of permissions
* @throws IllegalArgumentException if the length of the two arrays are not
* the same, if any array element is invalid, or if a principal
* appears multiple times in the {@code principals} array
*/
public Acl(String[] principals, int[] permissions) {
if (principals.length != permissions.length)
throw new IllegalArgumentException(
"The lengths of the principal and permission arrays are not the same.");
TreeMap tempPrincipalPermissions = new TreeMap();
int tempGlobalPermissions = 0;
for (int i = 0; i < principals.length; i++) {
// allow one * in 'principals' array, remove after loop
if (!ALL_PRINCIPALS.equals(principals[i]))
checkPrincipal(principals[i]);
checkPermissions(permissions[i]);
Integer permInt = new Integer(permissions[i]);
Object old = tempPrincipalPermissions.put(principals[i], permInt);
if (old != null)
throw new IllegalArgumentException("Principal '"
+ principals[i]
+ "' appears multiple times in the principal array.");
}
// set the global permissions if there was a * in the array
Object globalPermObj = tempPrincipalPermissions.remove(ALL_PRINCIPALS);
if (globalPermObj != null)
tempGlobalPermissions = ((Integer) globalPermObj).intValue();
principalPermissions = tempPrincipalPermissions;
globalPermissions = tempGlobalPermissions;
}
// ----- Private constructors -----//
/**
* Creates an instance identical to the {@code base} ACL except for
* the permissions of the given {@code principal}, which are
* overwritten with the given {@code permissions}.
*
* Assumes that the permissions parameter has been checked. All
* modifications of an {@code Acl} (add, delete, set) are done
* through this method.
*
* @param base The ACL that provides all permissions except for permissions
* of the given principal.
* @param principal The entity to which permission should be granted.
* @param permissions The set of permissions to be given. The parameter can
* be a logical {@code or} of the permission constants defined
* in this class.
*/
private Acl(Acl base, String principal, int permissions) {
// make a shallow copy of the permission table, the keys (String) and
// values (Integer) are immutable anyway
TreeMap tempPrincipalPermissions = (TreeMap) base.principalPermissions
.clone();
int tempGlobalPermissions = base.globalPermissions;
int deletedGlobalPerm = tempGlobalPermissions & ~permissions;
if (ALL_PRINCIPALS.equals(principal)) {
deleteFromAll(tempPrincipalPermissions, deletedGlobalPerm);
tempGlobalPermissions = permissions;
} else {
checkPrincipal(principal);
if (deletedGlobalPerm != 0)
throw new IllegalArgumentException(
"Cannot revoke globally set permissions ("
+ writeCommands(deletedGlobalPerm)
+ ") from a specific principal (" + principal
+ ").");
setPrincipalPermission(tempPrincipalPermissions, principal,
permissions);
}
principalPermissions = tempPrincipalPermissions;
globalPermissions = tempGlobalPermissions;
}
// ----- Public methods -----//
/**
* Checks whether the given object is equal to this {@code Acl}
* instance. Two {@code Acl} instances are equal if they allow the
* same set of permissions for the same set of principals.
*
* @param obj the object to compare with this {@code Acl} instance
* @return {@code true} if the parameter represents the same ACL as
* this instance
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Acl))
return false;
Acl other = (Acl) obj;
if (globalPermissions != other.globalPermissions
|| principalPermissions.size() != other.principalPermissions
.size())
return false;
// principalPermissions sets cannot be easily compared, because they are
// not canonical: the global permissions may or may not be present for
// each principal, without changing the meaning of the Acl object.
// Compare canonical string representations, inefficient but simple.
return toString().equals(other.toString());
}
/**
* Returns the hash code for this ACL instance. If two {@code Acl}
* instances are equal according to the {@link #equals} method, then calling
* this method on each of them must produce the same integer result.
*
* @return hash code for this ACL
*/
public int hashCode() {
// Using the hash code of the canonical string representation, because
// the principalPermissions set is not canonical (see above).
return toString().hashCode();
}
/**
* Use {@link #hashCode()} instead.
*
* @return Result of {@link #hashCode()}
* @deprecated Use correct method {@link #hashCode()};
*/
public int hashcode() {
return hashCode();
}
/**
* Create a new {@code Acl} instance from this {@code Acl} with
* the given permission added for the given principal. The already existing
* permissions of the principal are not affected.
*
* @param principal The entity to which permissions should be granted, or
* "*" to grant permissions to all principals.
* @param permissions The permissions to be given. The parameter can be a
* logical {@code or} of more permission constants defined in
* this class.
* @return a new {@code Acl} instance
* @throws IllegalArgumentException if {@code principal} is not a
* valid principal name or if {@code permissions} is not a
* valid combination of the permission constants defined in this
* class
*/
public synchronized Acl addPermission(String principal, int permissions) {
checkPermissions(permissions);
int oldPermissions = getPermissions(principal);
return setPermission(principal, oldPermissions | permissions);
}
/**
* Create a new {@code Acl} instance from this {@code Acl} with
* the given permission revoked from the given principal. Other permissions
* of the principal are not affected.
*
* Note, that it is not valid to revoke a permission from a specific
* principal if that permission is granted globally to all principals.
*
* @param principal The entity from which permissions should be revoked, or
* "*" to revoke permissions from all principals.
* @param permissions The permissions to be revoked. The parameter can be a
* logical {@code or} of more permission constants defined in
* this class.
* @return a new {@code Acl} instance
* @throws IllegalArgumentException if {@code principal} is not a
* valid principal name, if {@code permissions} is not a
* valid combination of the permission constants defined in this
* class, or if a globally granted permission would have been
* revoked from a specific principal
*/
public synchronized Acl deletePermission(String principal, int permissions) {
checkPermissions(permissions);
int oldPermissions = getPermissions(principal);
return setPermission(principal, oldPermissions & ~permissions);
}
/**
* Get the permissions associated to a given principal.
*
* @param principal The entity whose permissions to query, or "*"
* to query the permissions that are granted globally, to all
* principals
* @return The permissions of the given principal. The returned
* {@code int} is a bitmask of the permission constants defined
* in this class
* @throws IllegalArgumentException if {@code principal} is not a
* valid principal name
*/
public synchronized int getPermissions(String principal) {
int permissions = 0;
if (!(ALL_PRINCIPALS.equals(principal))) {
checkPrincipal(principal);
Object po = principalPermissions.get(principal);
if (po != null)
permissions = ((Integer) po).intValue();
}
return permissions | globalPermissions;
}
/**
* Check whether the given permissions are granted to a certain principal.
* The requested permissions are specified as a bitfield, for example
* {@code (Acl.ADD | Acl.DELETE | Acl.GET)}.
*
* @param principal The entity to check, or "*" to check whether
* the given permissions are granted to all principals globally
* @param permissions The permissions to check
* @return {@code true} if the principal holds all the given permissions
* @throws IllegalArgumentException if {@code principal} is not a
* valid principal name or if {@code permissions} is not a
* valid combination of the permission constants defined in this
* class
*/
public synchronized boolean isPermitted(String principal, int permissions) {
checkPermissions(permissions);
int hasPermissions = getPermissions(principal);
return (permissions & hasPermissions) == permissions;
}
/**
* Create a new {@code Acl} instance from this {@code Acl} where
* all permissions for the given principal are overwritten with the given
* permissions.
*
* Note, that when changing the permissions of a specific principal, it is
* not allowed to specify a set of permissions stricter than the global set
* of permissions (that apply to all principals).
*
* @param principal The entity to which permissions should be granted, or
* "*" to globally grant permissions to all principals.
* @param permissions The set of permissions to be given. The parameter is
* a bitmask of the permission constants defined in this class.
* @return a new {@code Acl} instance
* @throws IllegalArgumentException if {@code principal} is not a
* valid principal name, if {@code permissions} is not a
* valid combination of the permission constants defined in this
* class, or if a globally granted permission would have been
* revoked from a specific principal
*/
public synchronized Acl setPermission(String principal, int permissions) {
checkPermissions(permissions);
Acl newPermission = new Acl(this, principal, permissions);
return newPermission;
}
/**
* Get the list of principals who have any kind of permissions on this node.
* The list only includes those principals that have been explicitly
* assigned permissions (so "*" is never returned), globally set
* permissions naturally apply to all other principals as well.
*
* @return The array of principals having permissions on this node.
*/
public String[] getPrincipals() {
return (String[]) (principalPermissions.keySet().toArray(new String[0]));
}
/**
* Give the canonic string representation of this ACL. The operations are in
* the following order: {Add, Delete, Exec, Get, Replace}, principal names
* are sorted alphabetically.
*
* @return The string representation as defined in OMA DM.
*/
public synchronized String toString() {
String acl = null;
for (int i = 0; i < PERMISSION_CODES.length; i++)
acl = writeEntry(PERMISSION_CODES[i], acl);
return (acl != null) ? acl : "";
}
// ----- Private utility methods -----//
private String writeEntry(int command, String acl) {
String aclEntry = null;
if ((command & globalPermissions) > 0)
aclEntry = ALL_PRINCIPALS;
else {
// TreeMap guarantees alphabetical ordering of keys during traversal
Iterator i = principalPermissions.entrySet().iterator();
while (i.hasNext()) {
Map.Entry entry = (Map.Entry) i.next();
if ((command & ((Integer) entry.getValue()).intValue()) > 0)
aclEntry = appendEntry(aclEntry, '+', (String) entry
.getKey());
}
}
if (aclEntry == null)
return acl;
return appendEntry(acl, '&', writeCommands(command) + '=' + aclEntry);
}
private static void deleteFromAll(TreeMap principalPermissions, int perm) {
Iterator i = principalPermissions.entrySet().iterator();
while (i.hasNext()) {
Map.Entry entry = (Map.Entry) i.next();
setPrincipalPermission(principalPermissions, (String) entry
.getKey(), ((Integer) entry.getValue()).intValue() & ~perm);
}
}
private static void setPrincipalPermission(TreeMap principalPermissions,
String principal, int perm) {
if (perm == 0)
principalPermissions.remove(principal);
else
principalPermissions.put(principal, new Integer(perm));
}
private static String writeCommands(int command) {
String commandStr = null;
for (int i = 0; i < PERMISSION_CODES.length; i++)
if ((command & PERMISSION_CODES[i]) != 0)
commandStr = appendEntry(commandStr, ',', PERMISSION_NAMES[i]);
return (commandStr != null) ? commandStr : "";
}
private static String appendEntry(String base, char separator, String entry) {
return (base != null) ? base + separator + entry : entry;
}
private static int parseCommand(String command) {
int i = Arrays.asList(PERMISSION_NAMES).indexOf(command);
if (i == -1)
throw new IllegalArgumentException(
"Invalid ACL string: unknown command '" + command + "'.");
return PERMISSION_CODES[i];
}
private static void checkPermissions(int perm) {
if ((perm & ~ALL_PERMISSION) != 0)
throw new IllegalArgumentException("Invalid ACL permission value: "
+ perm);
}
private static void checkPrincipal(String principal) {
if (principal == null)
throw new IllegalArgumentException("Principal is null.");
checkServerId(principal, "Principal name contains illegal character");
}
private static void checkServerId(String serverId, String errorText) {
char[] chars = serverId.toCharArray();
for (int i = 0; i < chars.length; i++)
if ("*=+&".indexOf(chars[i]) != -1
|| Character.isWhitespace(chars[i]))
throw new IllegalArgumentException(errorText + " '" + chars[i]
+ "'.");
}
private static String[] split(String input, char sep, int limit) {
Vector v = new Vector();
boolean limited = (limit > 0);
int applied = 0;
int index = 0;
StringBuffer part = new StringBuffer();
while (index < input.length()) {
char ch = input.charAt(index);
if (ch != sep)
part.append(ch);
else {
++applied;
v.add(part.toString());
part = new StringBuffer();
}
++index;
if (limited && applied == limit - 1)
break;
}
while (index < input.length()) {
char ch = input.charAt(index);
part.append(ch);
++index;
}
v.add(part.toString());
int last = v.size();
if (0 == limit) {
for (int j = v.size() - 1; j >= 0; --j) {
String s = (String) v.elementAt(j);
if ("".equals(s))
--last;
else
break;
}
}
String[] ret = new String[last];
for (int i = 0; i < last; ++i)
ret[i] = (String) v.elementAt(i);
return ret;
}
}
osgi-compendium-4.3.0/src/info/dmtree/DmtEventListener.java 0000644 0001750 0001750 00000002672 11466514064 023630 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
/**
* Registered implementations of this class are notified via {@link DmtEvent}
* objects about important changes in the tree. Events are generated after every
* successful DMT change, and also when sessions are opened or closed. If a
* {@link DmtSession} is opened in atomic mode, DMT events are only sent when
* the session is committed, when the changes are actually performed.
*
* @version $Id: 275675e7ed60b346c1081e1b5bacdfa348ad8350 $
*/
public interface DmtEventListener {
/**
* {@code DmtAdmin} uses this method to notify the registered
* listeners about the change. This method is called asynchronously from the
* actual event occurrence.
*
* @param event the {@code DmtEvent} describing the change in detail
*/
void changeOccurred(DmtEvent event);
}
osgi-compendium-4.3.0/src/info/dmtree/DmtAdmin.java 0000644 0001750 0001750 00000034326 11564442770 022075 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
/**
* An interface providing methods to open sessions and register listeners. The
* implementation of {@code DmtAdmin} should register itself in the OSGi
* service registry as a service. {@code DmtAdmin} is the entry point for
* applications to use the DMT API.
*
* The {@code getSession} methods are used to open a session on a specified
* subtree of the DMT. A typical way of usage:
*
*
* The methods for opening a session take a node URI (the session root) as a
* parameter. All segments of the given URI must be within the segment length
* limit of the implementation, and the special characters '/' and '\' must be
* escaped (preceded by a '\'). Any string can be converted to a valid URI
* segment using the {@link Uri#mangle(String)} method.
*
* It is possible to specify a lock mode when opening the session (see lock type
* constants in {@link DmtSession}). This determines whether the session can run
* in parallel with other sessions, and the kinds of operations that can be
* performed in the session. All Management Objects constituting the device
* management tree must support read operations on their nodes, while support
* for write operations depends on the Management Object. Management Objects
* supporting write access may support transactional write, non-transactional
* write or both. Users of {@code DmtAdmin} should consult the Management
* Object specification and implementation for the supported update modes. If
* Management Object definition permits, implementations are encouraged to
* support both update modes.
*
* This interface also contains methods for manipulating the set of
* {@code DmtEventListener} objects that are called when the structure or
* content of the tree is changed. These methods are not needed in an OSGi
* environment, clients should register listeners through the Event Admin
* service.
*
* @version $Id: d34854b75471e0738ef0458a6cf154f0bd3a581d $
*/
public interface DmtAdmin {
/**
* Opens a {@code DmtSession} for local usage on a given subtree of
* the DMT with non transactional write lock. This call is equivalent to the
* following:
* {@code getSession(null, subtreeUri, DmtSession.LOCK_TYPE_EXCLUSIVE)}
*
* The {@code subtreeUri} parameter must contain an absolute URI. It
* can also be {@code null}, in this case the session is opened with
* the default session root, ".", that gives access to the whole
* tree.
*
* To perform this operation the caller must have {@code DmtPermission}
* for the {@code subtreeUri} node with the Get action present.
*
* @param subtreeUri the subtree on which DMT manipulations can be performed
* within the returned session
* @return a {@code DmtSession} object for the requested subtree
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code subtreeUri} or
* a segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code subtreeUri} is
* syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code subtreeUri}
* specifies a non-existing node
*
{@code SESSION_CREATION_TIMEOUT} if the operation
* timed out because of another ongoing session
*
{@code COMMAND_FAILED} if {@code subtreeUri}
* specifies a relative URI, or some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have
* {@code DmtPermission} for the given root node with the Get
* action present
*/
DmtSession getSession(String subtreeUri) throws DmtException;
/**
* Opens a {@code DmtSession} for local usage on a specific DMT
* subtree with a given lock mode. This call is equivalent to the
* following: {@code getSession(null, subtreeUri, lockMode)}
*
* The {@code subtreeUri} parameter must contain an absolute URI. It
* can also be {@code null}, in this case the session is opened with
* the default session root, ".", that gives access to the whole
* tree.
*
* To perform this operation the caller must have {@code DmtPermission}
* for the {@code subtreeUri} node with the Get action present.
*
* @param subtreeUri the subtree on which DMT manipulations can be performed
* within the returned session
* @param lockMode one of the lock modes specified in
* {@code DmtSession}
* @return a {@code DmtSession} object for the requested subtree
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code subtreeUri} or
* a segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code subtreeUri} is
* syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code subtreeUri}
* specifies a non-existing node
*
{@code FEATURE_NOT_SUPPORTED} if atomic sessions are
* not supported by the implementation and {@code lockMode}
* requests an atomic session
*
{@code SESSION_CREATION_TIMEOUT} if the operation
* timed out because of another ongoing session
*
{@code COMMAND_FAILED} if {@code subtreeUri}
* specifies a relative URI, if {@code lockMode} is unknown,
* or some unspecified error is encountered while attempting to
* complete the command
*
* @throws SecurityException if the caller does not have
* {@code DmtPermission} for the given root node with the Get
* action present
*/
DmtSession getSession(String subtreeUri, int lockMode) throws DmtException;
/**
* Opens a {@code DmtSession} on a specific DMT subtree using a
* specific lock mode on behalf of a remote principal. If local management
* applications are using this method then they should provide
* {@code null} as the first parameter. Alternatively they can use
* other forms of this method without providing a principal string.
*
* The {@code subtreeUri} parameter must contain an absolute URI. It
* can also be {@code null}, in this case the session is opened with
* the default session root, ".", that gives access to the whole
* tree.
*
* This method is guarded by {@code DmtPrincipalPermission} in case of
* remote sessions. In addition, the caller must have Get access rights
* (ACL in case of remote sessions, {@code DmtPermission} in case of
* local sessions) on the {@code subtreeUri} node to perform this
* operation.
*
* @param principal the identifier of the remote server on whose behalf the
* data manipulation is performed, or {@code null} for local
* sessions
* @param subtreeUri the subtree on which DMT manipulations can be performed
* within the returned session
* @param lockMode one of the lock modes specified in
* {@code DmtSession}
* @return a {@code DmtSession} object for the requested subtree
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code subtreeUri} or
* a segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code subtreeUri} is
* syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code subtreeUri}
* specifies a non-existing node
*
{@code PERMISSION_DENIED} if {@code principal} is
* not {@code null} and the ACL of the node does not allow the
* {@code Get} operation for the principal on the given root
* node
*
{@code FEATURE_NOT_SUPPORTED} if atomic sessions are
* not supported by the implementation and {@code lockMode}
* requests an atomic session
*
{@code SESSION_CREATION_TIMEOUT} if the operation
* timed out because of another ongoing session
*
{@code COMMAND_FAILED} if {@code subtreeUri}
* specifies a relative URI, if {@code lockMode} is unknown,
* or some unspecified error is encountered while attempting to
* complete the command
*
* @throws SecurityException in case of remote sessions, if the caller does
* not have the required {@code DmtPrincipalPermission} with a
* target matching the {@code principal} parameter, or in case
* of local sessions, if the caller does not have
* {@code DmtPermission} for the given root node with the Get
* action present
*/
DmtSession getSession(String principal, String subtreeUri, int lockMode)
throws DmtException;
/**
* Registers an event listener on behalf of a local application. The given
* listener will receive notification on all changes affecting the specified
* subtree. The subtree is specified by its root node URI. An event is
* delivered to the registered listener if at least one affected node is
* within this subtree. The events can also be filtered by specifying a
* bitmask of relevant event types (e.g.
* {@code DmtEvent.ADDED | DmtEvent.REPLACED | DmtEvent.SESSION_CLOSED}).
* Only event types included in the bitmask will be delivered to the
* listener.
*
* The listener will only receive the change notifications of nodes for
* which the registering application has the appropriate GET
* {@link info.dmtree.security.DmtPermission}.
*
* If the specified {@code listener} was already registered, calling
* this method will update the registration.
*
* @param type a bitmask of event types the caller is interested in
* @param uri the URI of the root node of a subtree, must not be
* {@code null}
* @param listener the listener to be registered, must not be
* {@code null}
* @throws SecurityException if the caller doesn't have the necessary GET
* {@code DmtPermission} for the given URI
* @throws NullPointerException if the {@code uri} or
* {@code listener} parameter is {@code null}
* @throws IllegalArgumentException if the {@code type} parameter
* contains invalid bits (not corresponding to any event type
* defined in {@code DmtEvent}), or if the {@code uri}
* parameter is invalid (is not an absolute URI or is syntactically
* incorrect)
*/
void addEventListener(int type, String uri, DmtEventListener listener);
/**
* Registers an event listener on behalf of a remote principal. The given
* listener will receive notification on all changes affecting the specified
* subtree. The subtree is specified by its root node URI. An event is
* delivered to the registered listener if at least one affected node is
* within this subtree. The events can also be filtered by specifying a
* bitmask of relevant event types (e.g.
* {@code DmtEvent.ADDED | DmtEvent.REPLACED | DmtEvent.SESSION_CLOSED}).
* Only event types included in the bitmask will be delivered to the
* listener.
*
* The listener will only receive the change notifications of nodes for
* which the node ACL grants GET access to the specified principal.
*
* If the specified {@code listener} was already registered, calling
* this method will update the registration.
*
* @param principal the management server identity the caller is acting on
* behalf of, must not be {@code null}
* @param type a bitmask of event types the caller is interested in
* @param uri the URI of the root node of a subtree, must not be
* {@code null}
* @param listener the listener to be registered, must not be
* {@code null}
* @throws SecurityException if the caller doesn't have the necessary
* {@code DmtPrincipalPermission} to use the specified
* principal
* @throws NullPointerException if the {@code principal},
* {@code uri} or {@code listener} parameter is
* {@code null}
* @throws IllegalArgumentException if the {@code type} parameter
* contains invalid bits (not corresponding to any event type
* defined in {@code DmtEvent}), or if the {@code uri}
* parameter is invalid (is not an absolute URI or is syntactically
* incorrect)
*/
void addEventListener(String principal, int type, String uri,
DmtEventListener listener);
/**
* Remove a previously registered listener. After this call, the listener
* will not receive change notifications.
*
* @param listener the listener to be unregistered, must not be
* {@code null}
* @throws NullPointerException if the {@code listener} parameter is
* {@code null}
*/
void removeEventListener(DmtEventListener listener);
}
osgi-compendium-4.3.0/src/info/dmtree/DmtData.java 0000644 0001750 0001750 00000074067 11564442770 021724 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
import java.util.Arrays;
import java.util.Hashtable;
// Possible enhancements to this class:
// * new constructors and get/set methods for b64, to access the encoded value
// * new constructors and get/set methods for date/time, for more convenient
// Java access
/**
* An immutable data structure representing the contents of a leaf or interior
* node. This structure represents only the value and the format property of the
* node, all other properties (like MIME type) can be set and read using the
* {@code DmtSession} interface.
*
* Different constructors are available to create nodes with different formats.
* Nodes of {@code null} format can be created using the static
* {@link #NULL_VALUE} constant instance of this class.
*
* {@link #FORMAT_RAW_BINARY} and {@link #FORMAT_RAW_STRING} enable the support
* of future data formats. When using these formats, the actual format name is
* specified as a {@code String}. The application is responsible for the
* proper encoding of the data according to the specified format.
*
* @version $Id: 6c2015a5ae3d771d4d09128428373b61fe832523 $
*/
public final class DmtData {
/**
* The node holds an OMA DM {@code int} value.
*/
public static final int FORMAT_INTEGER = 0x0001;
/**
* The node holds an OMA DM {@code float} value.
*/
public static final int FORMAT_FLOAT = 0x0002;
/**
* The node holds an OMA DM {@code chr} value.
*/
public static final int FORMAT_STRING = 0x0004;
/**
* The node holds an OMA DM {@code bool} value.
*/
public static final int FORMAT_BOOLEAN = 0x0008;
/**
* The node holds an OMA DM {@code date} value.
*/
public static final int FORMAT_DATE = 0x0010;
/**
* The node holds an OMA DM {@code time} value.
*/
public static final int FORMAT_TIME = 0x0020;
/**
* The node holds an OMA DM {@code bin} value. The value of the node
* corresponds to the Java {@code byte[]} type.
*/
public static final int FORMAT_BINARY = 0x0040;
/**
* The node holds an OMA DM {@code b64} value. Like
* {@link #FORMAT_BINARY}, this format is also represented by the Java
* {@code byte[]} type, the difference is only in the corresponding
* OMA DM format.
*/
public static final int FORMAT_BASE64 = 0x0080;
/**
* The node holds an OMA DM {@code xml} value.
*/
public static final int FORMAT_XML = 0x0100;
/**
* The node holds an OMA DM {@code null} value. This corresponds to
* the Java {@code null} type.
*/
public static final int FORMAT_NULL = 0x0200;
/**
* Format specifier of an internal node. An interior node can hold a Java
* object as value (see {@link DmtData#DmtData(Object)} and
* {@link DmtData#getNode()}). This value can be used by Java programs that
* know a specific URI understands the associated Java type. This type is
* further used as a return value of the {@link MetaNode#getFormat} method
* for interior nodes.
*/
public static final int FORMAT_NODE = 0x0400;
/**
* The node holds raw protocol data encoded as {@code String}. The
* {@link #getFormatName()} method can be used to get the actual format
* name.
*/
public static final int FORMAT_RAW_STRING = 0x0800;
/**
* The node holds raw protocol data encoded in binary format. The
* {@link #getFormatName()} method can be used to get the actual format
* name.
*/
public static final int FORMAT_RAW_BINARY = 0x1000;
private static final Hashtable FORMAT_NAMES = new Hashtable();
static {
FORMAT_NAMES.put(new Integer(FORMAT_BASE64), "b64");
FORMAT_NAMES.put(new Integer(FORMAT_BINARY), "bin");
FORMAT_NAMES.put(new Integer(FORMAT_BOOLEAN), "bool");
FORMAT_NAMES.put(new Integer(FORMAT_DATE), "date");
FORMAT_NAMES.put(new Integer(FORMAT_FLOAT), "float");
FORMAT_NAMES.put(new Integer(FORMAT_INTEGER), "int");
FORMAT_NAMES.put(new Integer(FORMAT_NODE), "node");
FORMAT_NAMES.put(new Integer(FORMAT_NULL), "null");
FORMAT_NAMES.put(new Integer(FORMAT_STRING), "chr");
FORMAT_NAMES.put(new Integer(FORMAT_TIME), "time");
FORMAT_NAMES.put(new Integer(FORMAT_XML), "xml");
}
/**
* Constant instance representing a leaf node of {@code null} format.
*/
public static final DmtData NULL_VALUE = new DmtData();
// FORMAT_NAMES must be initialized by the time the constr. is called
private final String str;
private final int integer;
private final float flt;
private final boolean bool;
private final byte[] bytes;
private final int format;
private final String formatName;
private final Object complex;
/**
* Create a {@code DmtData} instance of {@code null} format.
* This constructor is private and used only to create the public
* {@link #NULL_VALUE} constant.
*/
private DmtData() {
format = FORMAT_NULL;
formatName = getFormatName(format);
this.str = null;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.bytes = null;
this.complex = null;
}
/**
* Create a {@code DmtData} instance of {@code chr} format
* with the given string value. The {@code null} string argument is
* valid.
*
* @param str the string value to set
*/
public DmtData(String str) {
format = FORMAT_STRING;
formatName = getFormatName(format);
this.str = str;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.bytes = null;
this.complex = null;
}
/**
* Create a {@code DmtData} instance of {@code node} format
* with the given object value. The value represents complex data associated
* with an interior node.
*
* Certain interior nodes can support access to their subtrees through such
* complex values, making it simpler to retrieve or update all leaf nodes in
* a subtree.
*
* The given value must be a non-{@code null} immutable object.
*
* @param complex the complex data object to set
*/
public DmtData(Object complex) {
if(complex == null)
throw new NullPointerException("Complex data argument is null.");
format = FORMAT_NODE;
formatName = getFormatName(format);
this.complex = complex;
this.str = null;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.bytes = null;
}
/**
* Create a {@code DmtData} instance of the specified format and set
* its value based on the given string. Only the following string-based
* formats can be created using this constructor:
*
*
{@link #FORMAT_STRING} - value can be any string
*
{@link #FORMAT_XML} - value must contain an XML fragment (the
* validity is not checked by this constructor)
*
{@link #FORMAT_DATE} - value must be parseable to an ISO 8601
* calendar date in complete representation, basic format (pattern
* {@code CCYYMMDD})
*
{@link #FORMAT_TIME} - value must be parseable to an ISO 8601 time
* of day in either local time, complete representation, basic format
* (pattern {@code hhmmss}) or Coordinated Universal Time, basic format
* (pattern {@code hhmmssZ})
*
* The {@code null} string argument is only valid if the format is
* string or XML.
*
* @param value the string, XML, date or time value to set
* @param format the format of the {@code DmtData} instance to be
* created, must be one of the formats specified above
* @throws IllegalArgumentException if {@code format} is not one of
* the allowed formats, or {@code value} is not a valid
* string for the given format
* @throws NullPointerException if a date or time is constructed and
* {@code value} is {@code null}
*/
public DmtData(String value, int format) {
switch (format) {
case FORMAT_DATE:
checkDateFormat(value);
break;
case FORMAT_TIME:
checkTimeFormat(value);
break;
case FORMAT_STRING:
case FORMAT_XML:
break; // nothing to do, all string values are accepted
default:
throw new IllegalArgumentException(
"Invalid format in string constructor: " + format);
}
this.format = format;
this.formatName = getFormatName(format);
this.str = value;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.bytes = null;
this.complex = null;
}
/**
* Create a {@code DmtData} instance of {@code int} format and
* set its value.
*
* @param integer the integer value to set
*/
public DmtData(int integer) {
format = FORMAT_INTEGER;
formatName = getFormatName(format);
this.integer = integer;
this.str = null;
this.flt = 0;
this.bool = false;
this.bytes = null;
this.complex = null;
}
/**
* Create a {@code DmtData} instance of {@code float} format
* and set its value.
*
* @param flt the float value to set
*/
public DmtData(float flt) {
format = FORMAT_FLOAT;
formatName = getFormatName(format);
this.flt = flt;
this.str = null;
this.integer = 0;
this.bool = false;
this.bytes = null;
this.complex = null;
}
/**
* Create a {@code DmtData} instance of {@code bool} format
* and set its value.
*
* @param bool the boolean value to set
*/
public DmtData(boolean bool) {
format = FORMAT_BOOLEAN;
formatName = getFormatName(format);
this.bool = bool;
this.str = null;
this.integer = 0;
this.flt = 0;
this.bytes = null;
this.complex = null;
}
/**
* Create a {@code DmtData} instance of {@code bin} format and
* set its value.
*
* @param bytes the byte array to set, must not be {@code null}
* @throws NullPointerException if {@code bytes} is {@code null}
*/
public DmtData(byte[] bytes) {
if (bytes == null)
throw new NullPointerException("Binary data argument is null.");
format = FORMAT_BINARY;
formatName = getFormatName(format);
this.bytes = bytes;
this.str = null;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.complex = null;
}
/**
* Create a {@code DmtData} instance of {@code bin} or
* {@code b64} format and set its value. The chosen format is
* specified by the {@code base64} parameter.
*
* @param bytes the byte array to set, must not be {@code null}
* @param base64 if {@code true}, the new instance will have
* {@code b64} format, if {@code false}, it will have
* {@code bin} format
* @throws NullPointerException if {@code bytes} is {@code null}
*/
public DmtData(byte[] bytes, boolean base64) {
if (bytes == null)
throw new NullPointerException("Binary data argument is null.");
format = base64 ? FORMAT_BASE64 : FORMAT_BINARY;
formatName = getFormatName(format);
this.bytes = bytes;
this.str = null;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.complex = null;
}
/**
* Create a {@code DmtData} instance in {@link #FORMAT_RAW_STRING}
* format. The data is provided encoded as a {@code String}. The
* actual data format is specified in {@code formatName}. The
* encoding used in {@code data} must conform to this format.
*
* @param formatName the name of the format, must not be {@code null}
* @param data the data encoded according to the specified format, must not
* be {@code null}
* @throws NullPointerException if {@code formatName} or
* {@code data} is {@code null}
*/
public DmtData(String formatName, String data) {
if(formatName == null)
throw new NullPointerException("Format name argument is null.");
if(data == null)
throw new NullPointerException("Data argument is null.");
format = FORMAT_RAW_STRING;
this.formatName = formatName;
this.str = data;
this.bytes = null;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.complex = null;
}
/**
* Create a {@code DmtData} instance in {@link #FORMAT_RAW_BINARY}
* format. The data is provided encoded as binary. The actual data format is
* specified in {@code formatName}. The encoding used in
* {@code data} must conform to this format.
*
* @param formatName the name of the format, must not be {@code null}
* @param data the data encoded according to the specified format, must not
* be {@code null}
* @throws NullPointerException if {@code formatName} or
* {@code data} is {@code null}
*/
public DmtData(String formatName, byte[] data) {
if(formatName == null)
throw new NullPointerException("Format name argument is null.");
if(data == null)
throw new NullPointerException("Data argument is null.");
format = FORMAT_RAW_BINARY;
this.formatName = formatName;
this.bytes = (byte[]) data.clone();
this.str = null;
this.integer = 0;
this.flt = 0;
this.bool = false;
this.complex = null;
}
/**
* Gets the value of a node with string ({@code chr}) format.
*
* @return the string value
* @throws DmtIllegalStateException if the format of the node is not string
*/
public String getString() {
if (format == FORMAT_STRING)
return str;
throw new DmtIllegalStateException("DmtData value is not string.");
}
/**
* Gets the value of a node with date format. The returned date string is
* formatted according to the ISO 8601 definition of a calendar date in
* complete representation, basic format (pattern {@code CCYYMMDD}).
*
* @return the date value
* @throws DmtIllegalStateException if the format of the node is not date
*/
public String getDate() {
if (format == FORMAT_DATE)
return str;
throw new DmtIllegalStateException("DmtData value is not date.");
}
/**
* Gets the value of a node with time format. The returned time string is
* formatted according to the ISO 8601 definition of the time of day. The
* exact format depends on the value the object was initialized with: either
* local time, complete representation, basic format (pattern
* {@code hhmmss}) or Coordinated Universal Time, basic format (pattern
* {@code hhmmssZ}).
*
* @return the time value
* @throws DmtIllegalStateException if the format of the node is not time
*/
public String getTime() {
if (format == FORMAT_TIME)
return str;
throw new DmtIllegalStateException("DmtData value is not time.");
}
/**
* Gets the value of a node with {@code xml} format.
*
* @return the XML value
* @throws DmtIllegalStateException if the format of the node is not
* {@code xml}
*/
public String getXml() {
if (format == FORMAT_XML)
return str;
throw new DmtIllegalStateException("DmtData value is not XML.");
}
/**
* Gets the value of a node with integer ({@code int}) format.
*
* @return the integer value
* @throws DmtIllegalStateException if the format of the node is not integer
*/
public int getInt() {
if (format == FORMAT_INTEGER)
return integer;
throw new DmtIllegalStateException("DmtData value is not integer.");
}
/**
* Gets the value of a node with {@code float} format.
*
* @return the float value
* @throws DmtIllegalStateException if the format of the node is not
* {@code float}
*/
public float getFloat() {
if (format == FORMAT_FLOAT)
return flt;
throw new DmtIllegalStateException("DmtData value is not float.");
}
/**
* Gets the value of a node with boolean ({@code bool}) format.
*
* @return the boolean value
* @throws DmtIllegalStateException if the format of the node is not boolean
*/
public boolean getBoolean() {
if (format == FORMAT_BOOLEAN)
return bool;
throw new DmtIllegalStateException("DmtData value is not boolean.");
}
/**
* Gets the value of a node with binary ({@code bin}) format.
*
* @return the binary value
* @throws DmtIllegalStateException if the format of the node is not binary
*/
public byte[] getBinary() {
if (format == FORMAT_BINARY) {
byte[] bytesCopy = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++)
bytesCopy[i] = bytes[i];
return bytesCopy;
}
throw new DmtIllegalStateException("DmtData value is not a byte array.");
}
/**
* Gets the value of a node in raw binary ({@link #FORMAT_RAW_BINARY})
* format.
*
* @return the data value in raw binary format
* @throws DmtIllegalStateException if the format of the node is not raw binary
*/
public byte[] getRawBinary() {
if (format == FORMAT_RAW_BINARY)
return (byte[]) bytes.clone();
throw new DmtIllegalStateException(
"DmtData value is not in raw binary format.");
}
/**
* Gets the value of a node in raw {@code String}
* ({@link #FORMAT_RAW_STRING}) format.
*
* @return the data value in raw {@code String} format
* @throws DmtIllegalStateException if the format of the node is not raw
* {@code String}
*/
public String getRawString() {
if (format == FORMAT_RAW_STRING)
return str;
throw new DmtIllegalStateException(
"DmtData value is not in raw string format.");
}
/**
* Gets the value of a node with base 64 ({@code b64}) format.
*
* @return the binary value
* @throws DmtIllegalStateException if the format of the node is not base 64.
*/
public byte[] getBase64() {
if (format == FORMAT_BASE64) {
byte[] bytesCopy = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++)
bytesCopy[i] = bytes[i];
return bytesCopy;
}
throw new DmtIllegalStateException(
"DmtData value is not in base 64 format.");
}
/**
* Gets the complex data associated with an interior node ({@code node}
* format).
*
* Certain interior nodes can support access to their subtrees through
* complex values, making it simpler to retrieve or update all leaf nodes in
* the subtree.
*
* @return the data object associated with an interior node
* @throws DmtIllegalStateException if the format of the data is not
* {@code node}
*/
public Object getNode() {
if(format == FORMAT_NODE)
return complex;
throw new DmtIllegalStateException(
"DmtData does not contain interior node data.");
}
/**
* Get the node's format, expressed in terms of type constants defined in
* this class. Note that the 'format' term is a legacy from OMA DM, it is
* more customary to think of this as 'type'.
*
* @return the format of the node
*/
public int getFormat() {
return format;
}
/**
* Returns the format of this {@code DmtData} as {@code String}.
* For the predefined data formats this is the OMA DM defined name of the
* format. For {@link #FORMAT_RAW_STRING} and {@link #FORMAT_RAW_BINARY}
* this is the format specified when the object was created.
*
* @return the format name as {@code String}
*/
public String getFormatName() {
return formatName;
}
/**
* Get the size of the data. The returned value depends on the format of
* data in the node:
*
*
{@link #FORMAT_STRING}, {@link #FORMAT_XML}, {@link #FORMAT_BINARY},
* {@link #FORMAT_BASE64}, {@link #FORMAT_RAW_STRING}, and
* {@link #FORMAT_RAW_BINARY}: the length of the stored data, or 0 if
* the data is {@code null}
*
{@link #FORMAT_INTEGER} and {@link #FORMAT_FLOAT}: 4
*
{@link #FORMAT_DATE} and {@link #FORMAT_TIME}: the length of the
* date or time in its string representation
*
{@link #FORMAT_BOOLEAN}: 1
*
{@link #FORMAT_NODE}: -1 (unknown)
*
{@link #FORMAT_NULL}: 0
*
*
* @return the size of the data stored by this object
*/
public int getSize() {
switch (format) {
case FORMAT_STRING:
case FORMAT_XML:
case FORMAT_DATE:
case FORMAT_TIME:
case FORMAT_RAW_STRING:
return str == null ? 0 : str.length();
case FORMAT_BINARY:
case FORMAT_BASE64:
case FORMAT_RAW_BINARY:
return bytes.length;
case FORMAT_INTEGER:
case FORMAT_FLOAT:
return 4;
case FORMAT_BOOLEAN:
return 1;
case FORMAT_NODE:
return -1;
case FORMAT_NULL:
return 0;
}
return 0; // never reached
}
/**
* Gets the string representation of the {@code DmtData}. This
* method works for all formats.
*
* For string format data - including {@link #FORMAT_RAW_STRING} - the
* string value itself is returned, while for XML, date, time, integer,
* float, boolean and node formats the string form of the value is returned.
* Binary - including {@link #FORMAT_RAW_BINARY} - and base64 data is
* represented by two-digit hexadecimal numbers for each byte separated by
* spaces. The {@link #NULL_VALUE} data has the string form of
* "{@code null}". Data of string or XML format containing the Java
* {@code null} value is represented by an empty string.
*
* @return the string representation of this {@code DmtData} instance
*/
public String toString() {
switch (format) {
case FORMAT_STRING:
case FORMAT_XML:
case FORMAT_DATE:
case FORMAT_TIME:
case FORMAT_RAW_STRING:
return str == null ? "" : str;
case FORMAT_INTEGER:
return String.valueOf(integer);
case FORMAT_FLOAT:
return String.valueOf(flt);
case FORMAT_BOOLEAN:
return String.valueOf(bool);
case FORMAT_BINARY:
case FORMAT_BASE64:
case FORMAT_RAW_BINARY:
return getHexDump(bytes);
case FORMAT_NODE:
return complex.toString();
case FORMAT_NULL:
return "null";
}
return null; // never reached
}
/**
* Compares the specified object with this {@code DmtData} instance.
* Two {@code DmtData} objects are considered equal if their format
* is the same, and their data (selected by the format) is equal.
*
* In case of {@link #FORMAT_RAW_BINARY} and {@link #FORMAT_RAW_STRING}
* the textual name of the data format - as returned by
* {@link #getFormatName()} - must be equal as well.
*
* @param obj the object to compare with this {@code DmtData}
* @return true if the argument represents the same {@code DmtData}
* as this object
*/
public boolean equals(Object obj) {
if (!(obj instanceof DmtData))
return false;
DmtData other = (DmtData) obj;
if (format != other.format)
return false;
switch (format) {
case FORMAT_STRING:
case FORMAT_XML:
case FORMAT_DATE:
case FORMAT_TIME:
return str == null ? other.str == null : str.equals(other.str);
case FORMAT_INTEGER:
return integer == other.integer;
case FORMAT_FLOAT:
return flt == other.flt;
case FORMAT_BOOLEAN:
return bool == other.bool;
case FORMAT_BINARY:
case FORMAT_BASE64:
return Arrays.equals(bytes, other.bytes);
case FORMAT_NODE:
return complex.equals(other.complex);
case FORMAT_NULL:
return true;
case FORMAT_RAW_BINARY:
return formatName.equals(other.formatName)
&& Arrays.equals(bytes, other.bytes);
case FORMAT_RAW_STRING:
// in this case str cannot be null
return formatName.equals(other.formatName) && str.equals(other.str);
}
return false; // never reached
}
/**
* Returns the hash code value for this {@code DmtData} instance. The
* hash code is calculated based on the data (selected by the format) of
* this object.
*
* @return the hash code value for this object
*/
public int hashCode() {
switch (format) {
case FORMAT_STRING:
case FORMAT_XML:
case FORMAT_DATE:
case FORMAT_TIME:
case FORMAT_RAW_STRING:
return str == null ? 0 : str.hashCode();
case FORMAT_INTEGER:
return new Integer(integer).hashCode();
case FORMAT_FLOAT:
return new Float(flt).hashCode();
case FORMAT_BOOLEAN:
return new Boolean(bool).hashCode();
case FORMAT_BINARY:
case FORMAT_BASE64:
case FORMAT_RAW_BINARY:
return new String(bytes).hashCode();
case FORMAT_NODE:
return complex.hashCode();
case FORMAT_NULL:
return 0;
}
return 0; // never reached
}
private static void checkDateFormat(String value) {
if(value.length() != 8)
throw new IllegalArgumentException("Date string '" + value +
"' does not follow the format 'CCYYMMDD'.");
int year = checkNumber(value, "Date", 0, 4, 0, 9999);
int month = checkNumber(value, "Date", 4, 2, 1, 12);
int day = checkNumber(value, "Date", 6, 2, 1, 31);
// Date checking is not prepared for all special rules (for example
// historical leap years), production code could contain a full check.
// Day 31 is invalid for April, June, September and November
if((month == 4 || month == 6 || month == 9 || month == 11) && day == 31)
throw new IllegalArgumentException("Date string '" + value +
"' contains an invalid date.");
// February 29 is invalid except for leap years, Feb. 30-31 are invalid
if(month == 2 && day > 28 &&
!(day == 29 && year%4 == 0 && (year%100 != 0 || year%400 == 0)))
throw new IllegalArgumentException("Date string '" + value +
"' contains an invalid date.");
}
private static void checkTimeFormat(String value) {
if(value.length() > 0 && value.charAt(value.length()-1) == 'Z')
value = value.substring(0, value.length()-1);
if(value.length() != 6)
throw new IllegalArgumentException("Time string '" + value +
"' does not follow the format 'hhmmss' or 'hhmmssZ'.");
// Time checking is not prepared for all special rules (for example
// leap seconds), production code could contain a full check.
// if hour is 24, only 240000 should be allowed
checkNumber(value, "Time", 0, 2, 0, 24);
checkNumber(value, "Time", 2, 2, 0, 59);
checkNumber(value, "Time", 4, 2, 0, 59);
if(value.startsWith("24") && !value.startsWith("240000"))
throw new IllegalArgumentException("Time string is out of range.");
}
private static int checkNumber(String value, String name, int from,
int length, int min, int max) {
String part = value.substring(from, from+length);
int number;
try {
number = Integer.parseInt(part);
} catch(NumberFormatException e) {
throw new IllegalArgumentException(name + " string '" + value +
"' contains a non-numeric part.");
}
if(number < min || number > max)
throw new IllegalArgumentException("A segment of the " + name +
" string '" + value + "' is out of range.");
return number;
}
// character array of hexadecimal digits, used for printing binary data
private static char[] hex = "0123456789ABCDEF".toCharArray();
// generates a hexadecimal dump of the given binary data
private static String getHexDump(byte[] bytes) {
if (bytes.length == 0)
return "";
StringBuffer buf = new StringBuffer();
appendHexByte(buf, bytes[0]);
for (int i = 1; i < bytes.length; i++)
appendHexByte(buf.append(' '), bytes[i]);
return buf.toString();
}
private static void appendHexByte(StringBuffer buf, byte b) {
buf.append(hex[(b & 0xF0) >> 4]).append(hex[b & 0x0F]);
}
private static String getFormatName(int format) {
return (String) FORMAT_NAMES.get(new Integer(format));
}
}
osgi-compendium-4.3.0/src/info/dmtree/DmtEvent.java 0000644 0001750 0001750 00000012165 11564442770 022123 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
/**
* Event class storing the details of a change in the tree.
* {@code DmtEvent} is used by {@code DmtAdmin} to notify registered
* {@link DmtEventListener EventListeners} about important changes. Events are
* generated after every successful DMT change, and also when sessions are
* opened or closed. If a {@link DmtSession} is opened in atomic mode, DMT
* events are only sent when the session is committed, when the changes are
* actually performed.
*
* An event is generated for each group of nodes added, deleted, replaced,
* renamed or copied, in this order. Events are also generated when sessions are
* opened and closed.
*
* The {@code type} of the event describes the change that triggered the
* event delivery. Each event carries the unique identifier of the session in
* which the described change happened. The events describing changes in the DMT
* carry the list of affected nodes. In case of {@link #COPIED} or
* {@link #RENAMED} events, the event carries the list of new nodes as well.
*
* When a {@code DmtEvent} is delivered to a listener, the event contains
* only those node URIs that the listener has access to. This access control
* decision is based on the principal specified when the listener was
* registered:
*
*
If the listener was registered specifying an explicit principal, using
* the {@link DmtAdmin#addEventListener(String, int, String, DmtEventListener)}
* method, then the target node ACLs should be checked for providing GET access
* to the specified principal;
*
When the listener was registered without an explicit principal then the
* listener needs GET {@link info.dmtree.security.DmtPermission} for the
* corresponding node.
*
*
* @version $Id: 506872c6a60ee9170672b0e6cb2bc9688d70ad57 $
*/
public interface DmtEvent {
/**
* Event type indicating nodes that were added.
*/
int ADDED = 0x01;
/**
* Event type indicating nodes that were copied.
*/
int COPIED = 0x02;
/**
* Event type indicating nodes that were deleted.
*/
int DELETED = 0x04;
/**
* Event type indicating nodes that were renamed.
*/
int RENAMED = 0x08;
/**
* Event type indicating nodes that were replaced.
*/
int REPLACED = 0x10;
/**
* Event type indicating that a new session was opened.
*/
int SESSION_OPENED = 0x20;
/**
* Event type indicating that a session was closed. This type of event is
* sent when the session is closed by the client or becomes inactive for any
* other reason (session timeout, fatal errors in business methods, etc.).
*/
int SESSION_CLOSED = 0x40;
/**
* This method returns the type of this event.
*
* @return the type of this event.
*/
int getType();
/**
* This method returns the identifier of the session in which this event
* took place. The ID is guaranteed to be unique on a machine.
*
* @return the unique indetifier of the session that triggered the event
*/
int getSessionId();
/**
* This method can be used to query the subject nodes of this event. The
* method returns {@code null} for {@link #SESSION_OPENED} and
* {@link #SESSION_CLOSED}.
*
* The method returns only those affected nodes that the caller has the GET
* permission for (or in case of {@link #COPIED} or {@link #RENAMED} events,
* where the caller has GET permissions for either the source or the
* destination nodes). Therefore, it is possible that the method returns an
* empty array. All returned URIs are absolute.
*
* @return the array of affected nodes
* @see #getNewNodes
*/
String[] getNodes();
/**
* This method can be used to query the new nodes, when the type of the
* event is {@link #COPIED} or {@link #RENAMED}. For all other event types
* this method returns {@code null}.
*
* The array returned by this method runs parallel to the array returned by
* {@link #getNodes}, the elements in the two arrays contain the source and
* destination URIs for the renamed or copied nodes in the same order. All
* returned URIs are absolute.
*
* This method returns only those nodes where the caller has the GET
* permission for the source or destination node of the operation.
* Therefore, it is possible that the method returns an empty array.
*
* @return the array of newly created nodes
*/
String[] getNewNodes();
}
osgi-compendium-4.3.0/src/info/dmtree/packageinfo 0000644 0001750 0001750 00000000016 11405717676 021720 0 ustar drazzib drazzib version 1.0.2
osgi-compendium-4.3.0/src/info/dmtree/DmtSession.java 0000644 0001750 0001750 00000252760 11466514064 022471 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
import java.util.Date;
/**
* DmtSession provides concurrent access to the DMT. All DMT manipulation
* commands for management applications are available on the
* {@code DmtSession} interface. The session is associated with a root node
* which limits the subtree in which the operations can be executed within this
* session.
*
* Most of the operations take a node URI as parameter, which can be either an
* absolute URI (starting with "./") or a URI relative to the root
* node of the session. The empty string as relative URI means the root URI the
* session was opened with. All segments of a URI must be within the segment
* length limit of the implementation, and the special characters '/' and '\'
* must be escaped (preceded by a '\'). Any string can be converted to a valid
* URI segment using the {@link Uri#mangle(String)} method.
*
* If the URI specified does not correspond to a legitimate node in the tree an
* exception is thrown. The only exception is the {@link #isNodeUri(String)}
* method which returns {@code false} in case of an invalid URI.
*
* Each method of {@code DmtSession} that accesses the tree in any way can
* throw {@code DmtIllegalStateException} if the session has been closed or
* invalidated (due to timeout, fatal exceptions, or unexpectedly unregistered
* plugins).
*
* @version $Id: 3e598cf3f60216bdc289e749ad8703710c0d990d $
*/
public interface DmtSession {
/**
* Sessions created with {@code LOCK_TYPE_SHARED} lock allows
* read-only access to the tree, but can be shared between multiple readers.
*/
int LOCK_TYPE_SHARED = 0;
/**
* {@code LOCK_TYPE_EXCLUSIVE} lock guarantees full access to the
* tree, but can not be shared with any other locks.
*/
int LOCK_TYPE_EXCLUSIVE = 1;
/**
* {@code LOCK_TYPE_ATOMIC} is an exclusive lock with transactional
* functionality. Commands of an atomic session will either fail or succeed
* together, if a single command fails then the whole session will be rolled
* back.
*/
int LOCK_TYPE_ATOMIC = 2;
/**
* The session is open, all session operations are available.
*/
int STATE_OPEN = 0;
/**
* The session is closed, DMT manipulation operations are not available,
* they throw {@code DmtIllegalStateException} if tried.
*/
int STATE_CLOSED = 1;
/**
* The session is invalid because a fatal error happened. Fatal errors
* include the timeout of the session, any DmtException with the 'fatal'
* flag set, or the case when a plugin service is unregistered while in use
* by the session. DMT manipulation operations are not available, they throw
* {@code DmtIllegalStateException} if tried.
*/
int STATE_INVALID = 2;
/**
* Get the current state of this session.
*
* @return the state of the session, one of {@link #STATE_OPEN},
* {@link #STATE_CLOSED} and {@link #STATE_INVALID}
*/
int getState();
/**
* Gives the type of lock the session has.
*
* @return the lock type of the session, one of {@link #LOCK_TYPE_SHARED},
* {@link #LOCK_TYPE_EXCLUSIVE} and {@link #LOCK_TYPE_ATOMIC}
*/
int getLockType();
/**
* Gives the name of the principal on whose behalf the session was created.
* Local sessions do not have an associated principal, in this case
* {@code null} is returned.
*
* @return the identifier of the remote server that initiated the session,
* or {@code null} for local sessions
*/
String getPrincipal();
/**
* The unique identifier of the session. The ID is generated automatically,
* and it is guaranteed to be unique on a machine.
*
* @return the session identification number
*/
int getSessionId();
/**
* Get the root URI associated with this session. Gives "{@code .}"
* if the session was created without specifying a root, which means that
* the target of this session is the whole DMT.
*
* @return the root URI
*/
String getRootUri();
/**
* Commits a series of DMT operations issued in the current atomic session
* since the last transaction boundary. Transaction boundaries are the
* creation of this object that starts the session, and all subsequent
* {@link #commit} and {@link #rollback} calls.
*
* This method can fail even if all operations were successful. This can
* happen due to some multi-node semantic constraints defined by a specific
* implementation. For example, node A can be required to always have
* children A/B, A/C and A/D. If this condition is broken when
* {@code commit()} is executed, the method will fail, and throw a
* {@code METADATA_MISMATCH} exception.
*
* An error situation can arise due to the lack of a two phase commit
* mechanism in the underlying plugins. As an example, if plugin A has
* committed successfully but plugin B failed, the whole session must fail,
* but there is no way to undo the commit performed by A. To provide
* predictable behaviour, the commit operation should continue with the
* remaining plugins even after detecting a failure. All exceptions received
* from failed commits are aggregated into one
* {@code TRANSACTION_ERROR} exception thrown by this method.
*
* In many cases the tree is not the only way to manage a given part of the
* system. It may happen that while modifying some nodes in an atomic
* session, the underlying settings are modified in parallel outside the
* scope of the DMT. If this is detected during commit, an exception with
* the code {@code CONCURRENT_ACCESS} is thrown.
*
* @throws DmtException with the following possible error codes:
*
*
{@code METADATA_MISMATCH} if the operation failed
* because of meta-data restrictions
*
{@code CONCURRENT_ACCESS} if it is detected that some
* modification has been made outside the scope of the DMT to the
* nodes affected in the session's operations
*
{@code TRANSACTION_ERROR} if an error occurred during
* the commit of any of the underlying plugins
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was not opened using the
* {@code LOCK_TYPE_ATOMIC} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
void commit() throws DmtException;
/**
* Rolls back a series of DMT operations issued in the current atomic
* session since the last transaction boundary. Transaction boundaries are
* the creation of this object that starts the session, and all subsequent
* {@link #commit} and {@link #rollback} calls.
*
* @throws DmtException with the error code {@code ROLLBACK_FAILED}
* in case the rollback did not succeed
* @throws DmtIllegalStateException if the session was not opened using the
* {@code LOCK_TYPE_ATOMIC} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
void rollback() throws DmtException;
/**
* Closes a session. If the session was opened with atomic lock mode, the
* {@code DmtSession} must first persist the changes made to the DMT
* by calling {@code commit()} on all (transactional) plugins
* participating in the session. See the documentation of the
* {@link #commit} method for details and possible errors during this
* operation.
*
* The state of the session changes to {@code DmtSession.STATE_CLOSED}
* if the close operation completed successfully, otherwise it becomes
* {@code DmtSession.STATE_INVALID}.
*
* @throws DmtException with the following possible error codes:
*
*
{@code METADATA_MISMATCH} in case of atomic sessions,
* if the commit operation failed because of meta-data restrictions
*
{@code CONCURRENT_ACCESS} in case of atomic sessions,
* if the commit operation failed because of some modification
* outside the scope of the DMT to the nodes affected in the session
*
{@code TRANSACTION_ERROR} in case of atomic sessions,
* if an underlying plugin failed to commit
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if an underlying plugin failed
* to close, or if some unspecified error is encountered while
* attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
void close() throws DmtException;
/**
* Executes a node. This corresponds to the EXEC operation in OMA DM. This
* method cannot be called in a read-only session.
*
* The semantics of an execute operation and the data parameter it takes
* depends on the definition of the managed object on which the command is
* issued.
*
* @param nodeUri the node on which the execute operation is issued
* @param data the parameter of the execute operation, can be
* {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if the node does not exist and
* the plugin does not allow executing unexisting nodes
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Execute} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if the node cannot be
* executed according to the meta-data (does not have
* {@code MetaNode.CMD_EXECUTE} access type)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, if no DmtExecPlugin is associated with
* the node and the DmtAdmin can not execute the node, or if some
* unspecified error is encountered while attempting to complete the
* command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Exec action
* present
*
* @see #execute(String, String, String)
*/
void execute(String nodeUri, String data) throws DmtException;
/**
* Executes a node, also specifying a correlation ID for use in response
* notifications. This operation corresponds to the EXEC command in OMA DM.
* This method cannot be called in a read-only session.
*
* The semantics of an execute operation and the data parameter it takes
* depends on the definition of the managed object on which the command is
* issued. If a correlation ID is specified, it should be used as the
* {@code correlator} parameter for notifications sent in response to this
* execute operation.
*
* @param nodeUri the node on which the execute operation is issued
* @param correlator an identifier to associate this operation with any
* notifications sent in response to it, can be {@code null} if not
* needed
* @param data the parameter of the execute operation, can be
* {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if the node does not exist and
* the plugin does not allow executing unexisting nodes
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Execute} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if the node cannot be
* executed according to the meta-data (does not have
* {@code MetaNode.CMD_EXECUTE} access type)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, if no DmtExecPlugin is associated with
* the node, or if some unspecified error is encountered while
* attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Exec action
* present
* @see #execute(String, String)
*/
void execute(String nodeUri, String correlator, String data)
throws DmtException;
/**
* Get the Access Control List associated with a given node. The returned
* {@code Acl} object does not take inheritance into account, it
* gives the ACL specifically given to the node.
*
* @param nodeUri the URI of the node
* @return the Access Control List belonging to the node or
* {@code null} if none defined
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (the node does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException in case of local sessions, if the caller does
* not have {@code DmtPermission} for the node with the Get
* action present
* @see #getEffectiveNodeAcl
*/
Acl getNodeAcl(String nodeUri) throws DmtException;
/**
* Gives the Access Control List in effect for a given node. The returned
* {@code Acl} takes inheritance into account, that is if there is no
* ACL defined for the node, it will be derived from the closest ancestor
* having an ACL defined.
*
* @param nodeUri the URI of the node
* @return the Access Control List belonging to the node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (the node does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException in case of local sessions, if the caller does
* not have {@code DmtPermission} for the node with the Get
* action present
* @see #getNodeAcl
*/
Acl getEffectiveNodeAcl(String nodeUri) throws DmtException;
/**
* Set the Access Control List associated with a given node. To perform this
* operation, the caller needs to have replace rights ({@code Acl.REPLACE}
* or the corresponding Java permission depending on the session type) as
* described below:
*
*
if {@code nodeUri} specifies a leaf node, replace rights are
* needed on the parent of the node
*
if {@code nodeUri} specifies an interior node, replace rights
* on either the node or its parent are sufficient
*
*
* If the given {@code acl} is {@code null} or an empty ACL
* (not specifying any permissions for any principals), then the ACL of the
* node is deleted, and the node will inherit the ACL from its parent node.
*
* @param nodeUri the URI of the node
* @param acl the Access Control List to be set on the node, can be
* {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node or its parent
* (see above) does not allow the {@code Replace} operation
* for the associated principal
*
{@code COMMAND_NOT_ALLOWED} if the command attempts
* to set the ACL of the root node not to include Add rights for all
* principals
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException in case of local sessions, if the caller does
* not have {@code DmtPermission} for the node or its parent
* (see above) with the Replace action present
*/
void setNodeAcl(String nodeUri, Acl acl) throws DmtException;
/**
* Create a copy of a node or a whole subtree. Beside the structure and
* values of the nodes, most properties are also copied, with the exception
* of the ACL (Access Control List), Timestamp and Version properties.
*
* The copy method is essentially a convenience method that could be
* substituted with a sequence of retrieval and update operations. This
* determines the permissions required for copying. However, some
* optimization can be possible if the source and target nodes are all
* handled by DmtAdmin or by the same plugin. In this case, the handler
* might be able to perform the underlying management operation more
* efficiently: for example, a configuration table can be copied at once
* instead of reading each node for each entry and creating it in the new
* tree.
*
* This method may result in any of the errors possible for the contributing
* operations. Most of these are collected in the exception descriptions
* below, but for the full list also consult the documentation of
* {@link #getChildNodeNames(String)}, {@link #isLeafNode(String)},
* {@link #getNodeValue(String)}, {@link #getNodeType(String)},
* {@link #getNodeTitle(String)}, {@link #setNodeTitle(String, String)},
* {@link #createLeafNode(String, DmtData, String)} and
* {@link #createInteriorNode(String, String)}.
*
* @param nodeUri the node or root of a subtree to be copied
* @param newNodeUri the URI of the new node or root of a subtree
* @param recursive {@code false} if only a single node is copied,
* {@code true} if the whole subtree is copied
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or
* {@code newNodeUri} or any segment of them is too long, or
* if they have too many segments
*
{@code INVALID_URI} if {@code nodeUri} or
* {@code newNodeUri} is {@code null} or syntactically
* invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node, or if {@code newNodeUri}
* points to a node that cannot exist in the tree according to the
* meta-data (see {@link #getMetaNode(String)})
*
{@code NODE_ALREADY_EXISTS} if
* {@code newNodeUri} points to a node that already exists
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the copied node(s)
* does not allow the {@code Get} operation, or the ACL of
* the parent of the target node does not allow the {@code Add}
* operation for the associated principal
*
{@code COMMAND_NOT_ALLOWED} if {@code nodeUri}
* is an ancestor of {@code newNodeUri}, or if any of the
* implied retrieval or update operations are not allowed
*
{@code METADATA_MISMATCH} if any of the meta-data
* constraints of the implied retrieval or update operations are
* violated
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if either URI is not within
* the current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the copied node(s) with the Get
* action present, or for the parent of the target node with the Add
* action
*/
void copy(String nodeUri, String newNodeUri, boolean recursive)
throws DmtException;
/**
* Create an interior node. If the parent node does not exist, it is created
* automatically, as if this method were called for the parent URI. This way
* all missing ancestor nodes leading to the specified node are created. Any
* exceptions encountered while creating the ancestors are propagated to the
* caller of this method, these are not explicitly listed in the error
* descriptions below.
*
* If meta-data is available for the node, several checks are made before
* creating it. The node must have {@code MetaNode.CMD_ADD} access
* type, it must be defined as a non-permanent interior node, the node name
* must conform to the valid names, and the creation of the new node must
* not cause the maximum occurrence number to be exceeded.
*
* If the meta-data cannot be retrieved because the given node cannot
* possibly exist in the tree (it is not defined in the specification), the
* {@code NODE_NOT_FOUND} error code is returned (see
* {@link #getMetaNode(String)}).
*
* @param nodeUri the URI of the node to create
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a node that cannot exist in the tree (see above)
*
{@code NODE_ALREADY_EXISTS} if {@code nodeUri}
* points to a node that already exists
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the parent node does
* not allow the {@code Add} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the parent node is not
* an interior node, or in non-atomic sessions if the underlying
* plugin is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node could not be
* created because of meta-data restrictions (see above)
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the parent node with the Add
* action present
*/
void createInteriorNode(String nodeUri) throws DmtException;
/**
* Create an interior node with a given type. The type of interior node, if
* specified, is a URI identifying a DDF document. If the parent node does
* not exist, it is created automatically, as if
* {@link #createInteriorNode(String)} were called for the parent URI. This
* way all missing ancestor nodes leading to the specified node are created.
* Any exceptions encountered while creating the ancestors are propagated to
* the caller of this method, these are not explicitly listed in the error
* descriptions below.
*
* If meta-data is available for the node, several checks are made before
* creating it. The node must have {@code MetaNode.CMD_ADD} access
* type, it must be defined as a non-permanent interior node, the node name
* must conform to the valid names, and the creation of the new node must
* not cause the maximum occurrence number to be exceeded.
*
* If the meta-data cannot be retrieved because the given node cannot
* possibly exist in the tree (it is not defined in the specification), the
* {@code NODE_NOT_FOUND} error code is returned (see
* {@link #getMetaNode(String)}).
*
* Interior node type identifiers must follow the format defined in section
* 7.7.7.2 of the OMA Device Management Tree and Description document.
* Checking the validity of the type string does not have to be done by the
* DmtAdmin, this can be left to the plugin handling the node (if any), to
* avoid unnecessary double-checks.
*
* @param nodeUri the URI of the node to create
* @param type the type URI of the interior node, can be {@code null}
* if no node type is defined
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a node that cannot exist in the tree (see above)
*
{@code NODE_ALREADY_EXISTS} if {@code nodeUri}
* points to a node that already exists
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the parent node does
* not allow the {@code Add} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the parent node is not
* an interior node, or in non-atomic sessions if the underlying
* plugin is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node could not be
* created because of meta-data restrictions (see above)
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, if the type string is invalid (see
* above), or if some unspecified error is encountered while
* attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the parent node with the Add
* action present
* @see #createInteriorNode(String)
* @see
* OMA Device Management Tree and Description v1.2 draft
*/
void createInteriorNode(String nodeUri, String type) throws DmtException;
/**
* Create a leaf node with default value and MIME type. If a node does not
* have a default value or MIME type, this method will throw a
* {@code DmtException} with error code
* {@code METADATA_MISMATCH}. Note that a node might have a default
* value or MIME type even if there is no meta-data for the node or its
* meta-data does not specify the default.
*
* If the parent node does not exist, it is created automatically, as if
* {@link #createInteriorNode(String)} were called for the parent URI. This
* way all missing ancestor nodes leading to the specified node are created.
* Any exceptions encountered while creating the ancestors are propagated to
* the caller of this method, these are not explicitly listed in the error
* descriptions below.
*
* If meta-data is available for a node, several checks are made before
* creating it. The node must have {@code MetaNode.CMD_ADD} access
* type, it must be defined as a non-permanent leaf node, the node name must
* conform to the valid names, and the creation of the new node must not
* cause the maximum occurrence number to be exceeded.
*
* If the meta-data cannot be retrieved because the given node cannot
* possibly exist in the tree (it is not defined in the specification), the
* {@code NODE_NOT_FOUND} error code is returned (see
* {@link #getMetaNode(String)}).
*
* @param nodeUri the URI of the node to create
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a node that cannot exist in the tree (see above)
*
{@code NODE_ALREADY_EXISTS} if {@code nodeUri}
* points to a node that already exists
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the parent node does
* not allow the {@code Add} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the parent node is not
* an interior node, or in non-atomic sessions if the underlying
* plugin is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node could not be
* created because of meta-data restrictions (see above)
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the parent node with the Add
* action present
* @see #createLeafNode(String, DmtData)
*/
void createLeafNode(String nodeUri) throws DmtException;
/**
* Create a leaf node with a given value and the default MIME type. If the
* specified value is {@code null}, the default value is taken. If
* the node does not have a default MIME type or value (if needed), this
* method will throw a {@code DmtException} with error code
* {@code METADATA_MISMATCH}. Note that a node might have a default
* value or MIME type even if there is no meta-data for the node or its
* meta-data does not specify the default.
*
* If the parent node does not exist, it is created automatically, as if
* {@link #createInteriorNode(String)} were called for the parent URI. This
* way all missing ancestor nodes leading to the specified node are created.
* Any exceptions encountered while creating the ancestors are propagated to
* the caller of this method, these are not explicitly listed in the error
* descriptions below.
*
* If meta-data is available for a node, several checks are made before
* creating it. The node must have {@code MetaNode.CMD_ADD} access
* type, it must be defined as a non-permanent leaf node, the node name must
* conform to the valid names, the node value must conform to the value
* constraints, and the creation of the new node must not cause the maximum
* occurrence number to be exceeded.
*
* If the meta-data cannot be retrieved because the given node cannot
* possibly exist in the tree (it is not defined in the specification), the
* {@code NODE_NOT_FOUND} error code is returned (see
* {@link #getMetaNode(String)}).
*
* Nodes of {@code null} format can be created by using
* {@link DmtData#NULL_VALUE} as second argument.
*
* @param nodeUri the URI of the node to create
* @param value the value to be given to the new node, can be
* {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a node that cannot exist in the tree (see above)
*
{@code NODE_ALREADY_EXISTS} if {@code nodeUri}
* points to a node that already exists
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the parent node does
* not allow the {@code Add} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the parent node is not
* an interior node, or in non-atomic sessions if the underlying
* plugin is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node could not be
* created because of meta-data restrictions (see above)
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the parent node with the Add
* action present
*/
void createLeafNode(String nodeUri, DmtData value) throws DmtException;
/**
* Create a leaf node with a given value and MIME type. If the specified
* value or MIME type is {@code null}, their default values are
* taken. If the node does not have the necessary defaults, this method will
* throw a {@code DmtException} with error code
* {@code METADATA_MISMATCH}. Note that a node might have a default
* value or MIME type even if there is no meta-data for the node or its
* meta-data does not specify the default.
*
* If the parent node does not exist, it is created automatically, as if
* {@link #createInteriorNode(String)} were called for the parent URI. This
* way all missing ancestor nodes leading to the specified node are created.
* Any exceptions encountered while creating the ancestors are propagated to
* the caller of this method, these are not explicitly listed in the error
* descriptions below.
*
* If meta-data is available for a node, several checks are made before
* creating it. The node must have {@code MetaNode.CMD_ADD} access
* type, it must be defined as a non-permanent leaf node, the node name must
* conform to the valid names, the node value must conform to the value
* constraints, the MIME type must be among the listed types, and the
* creation of the new node must not cause the maximum occurrence number to
* be exceeded.
*
* If the meta-data cannot be retrieved because the given node cannot
* possibly exist in the tree (it is not defined in the specification), the
* {@code NODE_NOT_FOUND} error code is returned (see
* {@link #getMetaNode(String)}).
*
* Nodes of {@code null} format can be created by using
* {@link DmtData#NULL_VALUE} as second argument.
*
* The MIME type string must conform to the definition in RFC 2045. Checking
* its validity does not have to be done by the DmtAdmin, this can be left
* to the plugin handling the node (if any), to avoid unnecessary
* double-checks.
*
* @param nodeUri the URI of the node to create
* @param value the value to be given to the new node, can be
* {@code null}
* @param mimeType the MIME type to be given to the new node, can be
* {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a node that cannot exist in the tree (see above)
*
{@code NODE_ALREADY_EXISTS} if {@code nodeUri}
* points to a node that already exists
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the parent node does
* not allow the {@code Add} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the parent node is not
* an interior node, or in non-atomic sessions if the underlying
* plugin is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node could not be
* created because of meta-data restrictions (see above)
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, if {@code mimeType} is not a
* proper MIME type string (see above), or if some unspecified error
* is encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the parent node with the Add
* action present
* @see #createLeafNode(String, DmtData)
* @see RFC 2045
*/
void createLeafNode(String nodeUri, DmtData value, String mimeType)
throws DmtException;
/**
* Delete the given node. Deleting interior nodes is recursive, the whole
* subtree under the given node is deleted. It is not allowed to delete
* the root node of the session.
*
* If meta-data is available for a node, several checks are made before
* deleting it. The node must be non-permanent, it must have the
* {@code MetaNode.CMD_DELETE} access type, and if zero occurrences
* of the node are not allowed, it must not be the last one.
*
* @param nodeUri the URI of the node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Delete} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the target node is the
* root of the session, or in non-atomic sessions if the underlying
* plugin is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node could not be
* deleted because of meta-data restrictions (see above)
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Delete action
* present
*/
void deleteNode(String nodeUri) throws DmtException;
/**
* Rename a node. This operation only changes the name of the node (updating
* the timestamp and version properties if they are supported), the value
* and the other properties are not changed. The new name of the node must
* be provided, the new URI is constructed from the base of the old URI and
* the given name. It is not allowed to rename the root node of the session.
*
* If available, the meta-data of the original and the new nodes are checked
* before performing the rename operation. Neither node can be permanent,
* their leaf/interior property must match, and the name change must not
* violate any of the cardinality constraints. The original node must have
* the {@code MetaNode.CMD_REPLACE} access type, and the name of the
* new node must conform to the valid names.
*
* @param nodeUri the URI of the node to rename
* @param newName the new name property of the node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, if {@code nodeUri} has too many
* segments, or if {@code newName} is too long
*
{@code INVALID_URI} if {@code nodeUri} or
* {@code newName} is {@code null} or syntactically
* invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node, or if the new node is not defined
* in the tree according to the meta-data (see
* {@link #getMetaNode(String)})
*
{@code NODE_ALREADY_EXISTS} if there already exists a
* sibling of {@code nodeUri} with the name
* {@code newName}
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Replace} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the target node is the
* root of the session, or in non-atomic sessions if the underlying
* plugin is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node could not be
* renamed because of meta-data restrictions (see above)
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Replace action
* present
*/
void renameNode(String nodeUri, String newName) throws DmtException;
/**
* Set the value of a leaf or interior node to its default. The default
* can be defined by the node's {@code MetaNode}. The method throws a
* {@code METADATA_MISMATCH} exception if the node does not have a
* default value.
*
* @param nodeUri the URI of the node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Replace} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} in non-atomic sessions if
* the underlying plugin is read-only or does not support non-atomic
* writing
*
{@code METADATA_MISMATCH} if the node is permanent or
* cannot be modified according to the meta-data (does not have the
* {@code MetaNode.CMD_REPLACE} access type), or if there is
* no default value defined for this node
*
{@code FEATURE_NOT_SUPPORTED} if the specified node is
* an interior node and does not support Java object values
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Replace action
* present
* @see #setNodeValue
*/
void setDefaultNodeValue(String nodeUri) throws DmtException;
/**
* Set the value of a leaf or interior node. The format of the node is
* contained in the {@code DmtData} object. For interior nodes, the
* format must be {@code FORMAT_NODE}, while for leaf nodes this
* format must not be used.
*
* If the specified value is {@code null}, the default value is taken.
* In this case, if the node does not have a default value, this method will
* throw a {@code DmtException} with error code
* {@code METADATA_MISMATCH}. Nodes of {@code null} format can be
* set by using {@link DmtData#NULL_VALUE} as second argument.
*
* An Event of type REPLACE is sent out for a leaf node. A replaced interior
* node sends out events for each of its children in depth first order
* and node names sorted with Arrays.sort(String[]). When setting a value
* on an interior node, the values of the leaf nodes under it can change,
* but the structure of the subtree is not modified by the operation.
*
* @param nodeUri the URI of the node
* @param data the data to be set, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Replace} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the given data has
* {@code FORMAT_NODE} format but the node is a leaf node (or
* vice versa), or in non-atomic sessions if the underlying plugin
* is read-only or does not support non-atomic writing
*
{@code METADATA_MISMATCH} if the node is permanent or
* cannot be modified according to the meta-data (does not have the
* {@code MetaNode.CMD_REPLACE} access type), or if the given
* value does not conform to the meta-data value constraints
*
{@code FEATURE_NOT_SUPPORTED} if the specified node is
* an interior node and does not support Java object values
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Replace action
* present
*/
void setNodeValue(String nodeUri, DmtData data) throws DmtException;
/**
* Set the title property of a node. The length of the title string in UTF-8
* encoding must not exceed 255 bytes.
*
* @param nodeUri the URI of the node
* @param title the title text of the node, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Replace} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} in non-atomic sessions if
* the underlying plugin is read-only or does not support non-atomic
* writing
*
{@code METADATA_MISMATCH} if the node cannot be
* modified according to the meta-data (does not have the
* {@code MetaNode.CMD_REPLACE} access type)
*
{@code FEATURE_NOT_SUPPORTED} if the Title property
* is not supported by the DmtAdmin implementation or the
* underlying plugin
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the title string is too
* long, if the URI is not within the current session's subtree, or
* if some unspecified error is encountered while attempting to
* complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Replace action
* present
*/
void setNodeTitle(String nodeUri, String title) throws DmtException;
/**
* Set the type of a node. The type of leaf node is the MIME type of the
* data it contains. The type of an interior node is a URI identifying a DDF
* document.
*
* For interior nodes, a {@code null} type string means that there is
* no DDF document overriding the tree structure defined by the ancestors.
* For leaf nodes, it requests that the default MIME type is used for the
* given node. If the node does not have a default MIME type this method
* will throw a {@code DmtException} with error code
* {@code METADATA_MISMATCH}. Note that a node might have a default
* MIME type even if there is no meta-data for the node or its meta-data
* does not specify the default.
*
* MIME types must conform to the definition in RFC 2045. Interior node type
* identifiers must follow the format defined in section 7.7.7.2 of the OMA
* Device Management Tree and Description document. Checking the validity of
* the type string does not have to be done by the DmtAdmin, this can be
* left to the plugin handling the node (if any), to avoid unnecessary
* double-checks.
*
* @param nodeUri the URI of the node
* @param type the type of the node, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Replace} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} in non-atomic sessions if
* the underlying plugin is read-only or does not support non-atomic
* writing
*
{@code METADATA_MISMATCH} if the node is permanent or
* cannot be modified according to the meta-data (does not have the
* {@code MetaNode.CMD_REPLACE} access type), and in case of
* leaf nodes, if {@code null} is given and there is no
* default MIME type, or the given MIME type is not allowed
*
{@code TRANSACTION_ERROR} in an atomic session if the
* underlying plugin is read-only or does not support atomic writing
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, if the type string is invalid (see
* above), or if some unspecified error is encountered while
* attempting to complete the command
*
* @throws DmtIllegalStateException if the session was opened using the
* {@code LOCK_TYPE_SHARED} lock type, or if the session is
* already closed or invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Replace action
* present
* @see RFC 2045
* @see
* OMA Device Management Tree and Description v1.2 draft
*/
void setNodeType(String nodeUri, String type) throws DmtException;
/**
* Get the list of children names of a node. The returned array contains the
* names - not the URIs - of the immediate children nodes of the given node.
* The returned child names are mangled ({@link Uri#mangle(String)}). The elements
* are in no particular order. The returned array must not contain
* {@code null} entries.
*
* @param nodeUri the URI of the node
* @return the list of child node names as a string array or an empty string
* array if the node has no children
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the specified node is
* not an interior node
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
String[] getChildNodeNames(String nodeUri) throws DmtException;
/**
* Get the meta data which describes a given node. Meta data can only be
* inspected, it can not be changed.
*
* The {@code MetaNode} object returned to the client is the
* combination of the meta data returned by the data plugin (if any) plus
* the meta data returned by the DmtAdmin. If there are differences in the
* meta data elements known by the plugin and the DmtAdmin then the plugin
* specific elements take precedence.
*
* Note, that a node does not have to exist for having meta-data associated
* with it. This method may provide meta-data for any node that can possibly
* exist in the tree (any node defined in the specification). For nodes that
* are not defined, it may throw {@code DmtException} with the error
* code {@code NODE_NOT_FOUND}. To allow easier implementation of
* plugins that do not provide meta-data, it is allowed to return
* {@code null} for any node, regardless of whether it is defined or
* not.
*
* @param nodeUri the URI of the node
* @return a MetaNode which describes meta data information, can be
* {@code null} if there is no meta data available for the
* given node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a node that is not defined in the tree (see above)
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
MetaNode getMetaNode(String nodeUri) throws DmtException;
/**
* Get the size of the data in a leaf node. The returned value depends on
* the format of the data in the node, see the description of the
* {@link DmtData#getSize()} method for the definition of node size for each
* format.
*
* @param nodeUri the URI of the leaf node
* @return the size of the data in the node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code COMMAND_NOT_ALLOWED} if the specified node is
* not a leaf node
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code FEATURE_NOT_SUPPORTED} if the Size property is
* not supported by the DmtAdmin implementation or the underlying
* plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
* @see DmtData#getSize
*/
int getNodeSize(String nodeUri) throws DmtException;
/**
* Get the timestamp when the node was created or last modified.
*
* @param nodeUri the URI of the node
* @return the timestamp of the last modification
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code FEATURE_NOT_SUPPORTED} if the Timestamp
* property is not supported by the DmtAdmin implementation or the
* underlying plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
Date getNodeTimestamp(String nodeUri) throws DmtException;
/**
* Get the title of a node. There might be no title property set for a node.
*
* @param nodeUri the URI of the node
* @return the title of the node, or {@code null} if the node has no
* title
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code FEATURE_NOT_SUPPORTED} if the Title property
* is not supported by the DmtAdmin implementation or the
* underlying plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
String getNodeTitle(String nodeUri) throws DmtException;
/**
* Get the type of a node. The type of leaf node is the MIME type of the
* data it contains. The type of an interior node is a URI identifying a DDF
* document; a {@code null} type means that there is no DDF document
* overriding the tree structure defined by the ancestors.
*
* @param nodeUri the URI of the node
* @return the type of the node, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
String getNodeType(String nodeUri) throws DmtException;
/**
* Get the data contained in a leaf or interior node. When retrieving the
* value associated with an interior node, the caller must have rights to
* read all nodes in the subtree under the given node.
*
* @param nodeUri the URI of the node to retrieve
* @return the data of the node, can not be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node (and the ACLs
* of all its descendants in case of interior nodes) do not allow
* the {@code Get} operation for the associated principal
*
{@code METADATA_MISMATCH} if the node value cannot be
* retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code FEATURE_NOT_SUPPORTED} if the specified node is
* an interior node and does not support Java object values
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node (and all its descendants
* in case of interior nodes) with the Get action present
*/
DmtData getNodeValue(String nodeUri) throws DmtException;
/**
* Get the version of a node. The version can not be set, it is calculated
* automatically by the device. It is incremented modulo 0x10000 at every
* modification of the value or any other property of the node, for both
* leaf and interior nodes. When a node is created the initial value is 0.
*
* @param nodeUri the URI of the node
* @return the version of the node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code FEATURE_NOT_SUPPORTED} if the Version property
* is not supported by the DmtAdmin implementation or the
* underlying plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
int getNodeVersion(String nodeUri) throws DmtException;
/**
* Tells whether a node is a leaf or an interior node of the DMT.
*
* @param nodeUri the URI of the node
* @return true if the given node is a leaf node
* @throws DmtException with the following possible error codes:
*
*
{@code URI_TOO_LONG} if {@code nodeUri} or a
* segment of it is too long, or if it has too many segments
*
{@code INVALID_URI} if {@code nodeUri} is
* {@code null} or syntactically invalid
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a non-existing node
*
{@code PERMISSION_DENIED} if the session is
* associated with a principal and the ACL of the node does not
* allow the {@code Get} operation for the associated
* principal
*
{@code METADATA_MISMATCH} if node information cannot
* be retrieved according to the meta-data (it does not have
* {@code MetaNode.CMD_GET} access type)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if the URI is not within the
* current session's subtree, or if some unspecified error is
* encountered while attempting to complete the command
*
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
boolean isLeafNode(String nodeUri) throws DmtException;
/**
* Check whether the specified URI corresponds to a valid node in the DMT.
*
* @param nodeUri the URI to check
* @return true if the given node exists in the DMT
* @throws DmtIllegalStateException if the session is already closed or
* invalidated
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation, or,
* in case of local sessions, if the caller does not have
* {@code DmtPermission} for the node with the Get action
* present
*/
boolean isNodeUri(String nodeUri);
}
osgi-compendium-4.3.0/src/info/dmtree/Uri.java 0000644 0001750 0001750 00000051216 11564442770 021134 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
/**
* This class contains static utility methods to manipulate DMT URIs.
*
* Syntax of valid DMT URIs:
*
*
A slash ({@code '/'} \u002F) is the separator of the node names.
* Slashes used in node name must therefore be escaped using a backslash slash (
* {@code "\/"}). The backslash must be escaped with a double backslash sequence. A
* backslash found must be ignored when it is not followed by a slash or
* backslash.
*
The node name can be constructed using full Unicode character set (except
* the Supplementary code, not being supported by CLDC/CDC). However, using the
* full Unicode character set for node names is discouraged because the encoding
* in the underlying storage as well as the encoding needed in communications
* can create significant performance and memory usage overhead. Names that are
* restricted to the URI set {@code [-a-zA-Z0-9_.!~*'()]} are most efficient.
*
URIs used in the DMT must be treated and interpreted as case sensitive.
*
No End Slash: URI must not end with the delimiter slash ({@code '/'}
* \u002F). This implies that the root node must be denoted as
* {@code "."} and not {@code "./"}.
*
No parent denotation: URI must not be constructed using the character
* sequence {@code "../"} to traverse the tree upwards.
*
Single Root: The character sequence {@code "./"} must not be used
* anywhere else but in the beginning of a URI.
*
*
* @version $Id: 5289414c7bb0af15b3db2b8d2174181321f739c4 $
*/
public final class Uri {
/*
* NOTE: An implementor may also choose to replace this class in
* their distribution with a class that directly interfaces with the
* info.dmtree implementation. This replacement class MUST NOT alter the
* public/protected signature of this class.
*/
/*
* This class will load the class named
* by the org.osgi.vendor.dmtree.DigestDelegate property. This class will call
* the public static byte[] digest(byte[]) method on that class.
*/
private static class ImplHolder implements PrivilegedAction {
// the name of the system property containing the digest delegate class name
private static final String DIGEST_DELEGATE_PROPERTY =
"org.osgi.vendor.dmtree.DigestDelegate";
// the Method where message digest requests can be delegated
static final Method digestMethod;
static {
digestMethod = (Method) AccessController.doPrivileged(new ImplHolder());
}
private ImplHolder() {
}
public Object run() {
String className = System
.getProperty(DIGEST_DELEGATE_PROPERTY);
if (className == null) {
throw new NoClassDefFoundError("Digest " +
"delegate class property '" +
DIGEST_DELEGATE_PROPERTY +
"' must be set to a " +
"class which implements a " +
"public static byte[] digest(byte[]) method.");
}
Class delegateClass;
try {
delegateClass = Class.forName(className);
}
catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.toString());
}
Method result;
try {
result = delegateClass.getMethod("digest",
new Class[] {byte[].class});
}
catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.toString());
}
if (!Modifier.isStatic(result.getModifiers())) {
throw new NoSuchMethodError(
"digest method must be static");
}
return result;
}
}
// the name of the system property containing the URI segment length limit
private static final String SEGMENT_LENGTH_LIMIT_PROPERTY =
"org.osgi.impl.service.dmt.uri.limits.segmentlength";
// the smallest valid value for the URI segment length limit
private static final int MINIMAL_SEGMENT_LENGTH_LIMIT = 32;
// contains the maximum length of node names
private static final int segmentLengthLimit;
static {
segmentLengthLimit = ((Integer) AccessController
.doPrivileged(new PrivilegedAction() {
public Object run() {
String limitString = System.getProperty(SEGMENT_LENGTH_LIMIT_PROPERTY);
int limit = MINIMAL_SEGMENT_LENGTH_LIMIT; // min. used as default
try {
int limitInt = Integer.parseInt(limitString);
if(limitInt >= MINIMAL_SEGMENT_LENGTH_LIMIT)
limit = limitInt;
} catch(NumberFormatException e) {}
return new Integer(limit);
}
})).intValue();
}
// base64 encoding table, modified for use in node name mangling
private static final char BASE_64_TABLE[] = {
'A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X',
'Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3',
'4','5','6','7','8','9','+','_', // !!! this differs from base64
};
/**
* A private constructor to suppress the default public constructor.
*/
private Uri() {}
/**
* Returns a node name that is valid for the tree operation methods, based
* on the given node name. This transformation is not idempotent, so it must
* not be called with a parameter that is the result of a previous
* {@code mangle} method call.
*
* Node name mangling is needed in the following cases:
*
*
if the name contains '/' or '\' characters
*
if the length of the name exceeds the limit defined by the
* implementation
*
*
* A node name that does not suffer from either of these problems is
* guaranteed to remain unchanged by this method. Therefore the client may
* skip the mangling if the node name is known to be valid (though it is
* always safe to call this method).
*
* The method returns the normalized {@code nodeName} as described
* below. Invalid node names are normalized in different ways, depending on
* the cause. If the length of the name does not exceed the limit, but the
* name contains '/' or '\' characters, then these are simply escaped by
* inserting an additional '\' before each occurrence. If the length of the
* name does exceed the limit, the following mechanism is used to normalize
* it:
*
*
the SHA 1 digest of the name is calculated
*
the digest is encoded with the base 64 algorithm
*
all '/' characters in the encoded digest are replaced with '_'
*
trailing '=' signs are removed
*
*
* @param nodeName the node name to be mangled (if necessary), must not be
* {@code null} or empty
* @return the normalized node name that is valid for tree operations
* @throws NullPointerException if {@code nodeName} is
* {@code null}
* @throws IllegalArgumentException if {@code nodeName} is empty
*/
public static String mangle(String nodeName) {
return mangle(nodeName, getMaxSegmentNameLength());
}
/**
* Construct a URI from the specified URI segments. The segments must
* already be mangled.
*
* If the specified path is an empty array then an empty URI
* ({@code ""}) is returned.
*
* @param path a possibly empty array of URI segments, must not be
* {@code null}
* @return the URI created from the specified segments
* @throws NullPointerException if the specified path or any of its
* segments are {@code null}
* @throws IllegalArgumentException if the specified path contains too many
* or malformed segments or the resulting URI is too long
*/
public static String toUri(String[] path) {
if (0 == path.length) {
return "";
}
if (path.length > getMaxUriSegments()) {
throw new IllegalArgumentException(
"Path contains too many segments.");
}
StringBuffer uri = new StringBuffer();
int uriLength = 0;
for (int i = 0; i < path.length; ++i) {
// getSegmentLength throws exceptions on malformed segments.
int segmentLength = getSegmentLength(path[i]);
if (segmentLength > getMaxSegmentNameLength()) {
throw new IllegalArgumentException("URI segment too long.");
}
if (i > 0) {
uri.append('/');
uriLength++;
}
uriLength += segmentLength;
uri.append(path[i]);
}
if (uriLength > getMaxUriLength()) {
throw new IllegalArgumentException("URI too long.");
}
return uri.toString();
}
/**
* This method returns the length of a URI segment. The length of the URI
* segment is defined as the number of bytes in the unescaped, UTF-8 encoded
* represenation of the segment.
*
* The method verifies that the URI segment is well-formed.
*
* @param segment the URI segment
* @return URI segment length
* @throws NullPointerException if the specified segment is
* {@code null}
* @throws IllegalArgumentException if the specified URI segment is
* malformed
*/
private static int getSegmentLength(String segment) {
if (segment.length() == 0)
throw new IllegalArgumentException("URI segment is empty.");
StringBuffer newsegment = new StringBuffer(segment);
int i = 0;
while (i < newsegment.length()) { // length can decrease during the loop!
if (newsegment.charAt(i) == '\\') {
if (i == newsegment.length() - 1) // last character cannot be a '\'
throw new IllegalArgumentException(
"URI segment ends with the escape character.");
newsegment.deleteCharAt(i); // remove the extra '\'
} else if (newsegment.charAt(i) == '/')
throw new IllegalArgumentException(
"URI segment contains an unescaped '/' character.");
i++;
}
if (newsegment.toString().equals(".."))
throw new IllegalArgumentException(
"URI segment must not be \"..\".");
try {
return newsegment.toString().getBytes("UTF-8").length;
} catch (UnsupportedEncodingException e) {
// This should never happen. All implementations must support
// UTF-8 encoding;
throw new RuntimeException(e.toString());
}
}
/**
* Split the specified URI along the path separator '/' charaters and return
* an array of URI segments. Special characters in the returned segments are
* escaped. The returned array may be empty if the specifed URI was empty.
*
* @param uri the URI to be split, must not be {@code null}
* @return an array of URI segments created by splitting the specified URI
* @throws NullPointerException if the specified URI is {@code null}
* @throws IllegalArgumentException if the specified URI is malformed
*/
public static String[] toPath(String uri) {
if (uri == null)
throw new NullPointerException("'uri' parameter is null.");
if (!isValidUri(uri))
throw new IllegalArgumentException("Malformed URI: " + uri);
if (uri.length() == 0)
return new String[] {};
List segments = new ArrayList();
StringBuffer segment = new StringBuffer();
boolean escape = false;
for (int i = 0; i < uri.length(); i++) {
char ch = uri.charAt(i);
if (escape) {
if(ch == '/' || ch == '\\')
segment.append('\\');
segment.append(ch);
escape = false;
} else if (ch == '/') {
segments.add(segment.toString());
segment = new StringBuffer();
} else if (ch == '\\') {
escape = true;
} else
segment.append(ch);
}
if (segment.length() > 0) {
segments.add(segment.toString());
}
return (String[]) segments.toArray(new String[segments.size()]);
}
/**
* Returns the maximum allowed number of URI segments. The returned value is
* implementation specific.
*
* The return value of {@code Integer.MAX_VALUE} indicates that there
* is no upper limit on the number of URI segments.
*
* @return maximum number of URI segments supported by the implementation
*/
public static int getMaxUriSegments() {
return Integer.MAX_VALUE;
}
/**
* Returns the maximum allowed length of a URI. The value is implementation
* specific. The length of the URI is defined as the number of bytes in the
* unescaped, UTF-8 encoded represenation of the URI.
*
* The return value of {@code Integer.MAX_VALUE} indicates that there
* is no upper limit on the length of URIs.
*
* @return maximum URI length supported by the implementation
*/
public static int getMaxUriLength() {
return Integer.MAX_VALUE;
}
/**
* Returns the maximum allowed length of a URI segment. The value is
* implementation specific. The length of the URI segment is defined as the
* number of bytes in the unescaped, UTF-8 encoded represenation of the
* segment.
*
* The return value of {@code Integer.MAX_VALUE} indicates that there
* is no upper limit on the length of segment names.
*
* @return maximum URI segment length supported by the implementation
*/
public static int getMaxSegmentNameLength() {
return segmentLengthLimit;
}
/**
* Checks whether the specified URI is an absolute URI. An absolute URI
* contains the complete path to a node in the DMT starting from the DMT
* root (".").
*
* @param uri the URI to be checked, must not be {@code null} and must
* contain a valid URI
* @return whether the specified URI is absolute
* @throws NullPointerException if the specified URI is {@code null}
* @throws IllegalArgumentException if the specified URI is malformed
*/
public static boolean isAbsoluteUri(String uri) {
if( null == uri ) {
throw new NullPointerException("'uri' parameter is null.");
}
if( !isValidUri(uri) )
throw new IllegalArgumentException("Malformed URI: " + uri);
return uri.equals(".") || uri.equals("\\.") || uri.startsWith("./")
|| uri.startsWith("\\./");
}
/**
* Checks whether the specified URI is valid. A URI is considered valid if
* it meets the following constraints:
*
*
the URI is not {@code null};
*
the URI follows the syntax defined for valid DMT URIs;
*
the length of the URI is not more than {@link #getMaxUriLength()};
*
the URI doesn't contain more than {@link #getMaxUriSegments()}
* segments;
*
the length of each segment of the URI is less than or equal to
* {@link #getMaxSegmentNameLength()}.
*
* The exact definition of the length of a URI and its segments is
* given in the descriptions of the {@code getMaxUriLength()} and
* {@code getMaxSegmentNameLength()} methods.
*
* @param uri the URI to be validated
* @return whether the specified URI is valid
*/
public static boolean isValidUri(String uri) {
if (null == uri)
return false;
int paramLen = uri.length();
if( paramLen == 0 )
return true;
if( uri.charAt(0) == '/' || uri.charAt(paramLen-1) == '\\' )
return false;
int processedUriLength = 0;
int segmentNumber = 0;
// append a '/' to indicate the end of the last segment (the URI in the
// parameter must not end with a '/')
uri += '/';
paramLen++;
int start = 0;
for(int i = 1; i < paramLen; i++) { // first character is not a '/'
if(uri.charAt(i) == '/' && uri.charAt(i-1) != '\\') {
segmentNumber++;
String segment = uri.substring(start, i);
if(segmentNumber > 1 && segment.equals("."))
return false; // the URI contains the "." node name at a
// position other than the beginning of the URI
int segmentLength;
try {
// also checks that the segment is valid
segmentLength = getSegmentLength(segment);
} catch(IllegalArgumentException e) {
return false;
}
if(segmentLength > getMaxSegmentNameLength())
return false;
// the extra byte is for the separator '/' (will be deducted
// again for the last segment of the URI)
processedUriLength += segmentLength + 1;
start = i+1;
}
}
processedUriLength--; // remove the '/' added to the end of the URI
return segmentNumber <= getMaxUriSegments() &&
processedUriLength <= getMaxUriLength();
}
// Non-public fields and methods
// package private method for testing purposes
static String mangle(String nodeName, int limit) {
if(nodeName == null)
throw new NullPointerException(
"The 'nodeName' parameter must not be null.");
if(nodeName.equals(""))
throw new IllegalArgumentException(
"The 'nodeName' parameter must not be empty.");
if(nodeName.length() > limit)
// create node name hash
return getHash(nodeName);
// escape any '/' and '\' characters in the node name
StringBuffer nameBuffer = new StringBuffer(nodeName);
for(int i = 0; i < nameBuffer.length(); i++) // 'i' can increase in loop
if(nameBuffer.charAt(i) == '\\' || nameBuffer.charAt(i) == '/')
nameBuffer.insert(i++, '\\');
return nameBuffer.toString();
}
private static String getHash(String from) {
byte[] byteStream;
try {
byteStream = from.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e) {
// There's no way UTF-8 encoding is not implemented...
throw new IllegalStateException("there's no UTF-8 encoder here!");
}
byte[] digest = digestMessage(byteStream);
// very dumb base64 encoder code. There is no need for multiple lines
// or trailing '='-s....
// also, we hardcoded the fact that sha-1 digests are 20 bytes long
StringBuffer sb = new StringBuffer(digest.length*2);
for(int i=0;i<6;i++) {
int d0 = digest[i*3]&0xff;
int d1 = digest[i*3+1]&0xff;
int d2 = digest[i*3+2]&0xff;
sb.append(BASE_64_TABLE[d0>>2]);
sb.append(BASE_64_TABLE[(d0<<4|d1>>4)&63]);
sb.append(BASE_64_TABLE[(d1<<2|d2>>6)&63]);
sb.append(BASE_64_TABLE[d2&63]);
}
int d0 = digest[18]&0xff;
int d1 = digest[19]&0xff;
sb.append(BASE_64_TABLE[d0>>2]);
sb.append(BASE_64_TABLE[(d0<<4|d1>>4)&63]);
sb.append(BASE_64_TABLE[(d1<<2)&63]);
return sb.toString();
}
private static byte[] digestMessage(byte[] byteStream) {
try {
try {
return (byte[]) ImplHolder.digestMethod.invoke(null, new Object[] {
byteStream});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e.toString());
}
}
}
osgi-compendium-4.3.0/src/info/dmtree/spi/ 0000755 0001750 0001750 00000000000 11632153414 020306 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/info/dmtree/spi/package-info.java 0000644 0001750 0001750 00000003113 11564442770 023505 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Device Management Tree SPI Package Version 1.0.
*
*
* This package contains the interface classes that compose the Device Management
* SPI (Service Provider Interface). These interfaces are implemented by DMT plugins;
* users of the {@code DmtAdmin} interface do not interact directly with these.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: info.dmtree.spi; version="[1.0,1.1)"}
*
* @version $Id: d606bdeacd82efe829ce829dabbf5eedb1ae4b42 $
*/
package info.dmtree.spi;
osgi-compendium-4.3.0/src/info/dmtree/spi/DataPlugin.java 0000644 0001750 0001750 00000014676 11564442770 023231 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.spi;
import info.dmtree.DmtException;
import info.dmtree.DmtSession;
/**
* An implementation of this interface takes the responsibility of handling data
* requests in a subtree of the DMT.
*
* In an OSGi environment such implementations should be registered at the OSGi
* service registry specifying the list of root node URIs in a
* {@code String} array in the {@code dataRootURIs} registration
* parameter.
*
* When the first reference in a session is made to a node handled by this
* plugin, the DmtAdmin calls one of the {@code open...} methods to
* retrieve a plugin session object for processing the request. The called
* method depends on the lock type of the current session. In case of
* {@link #openReadWriteSession(String[], DmtSession)} and
* {@link #openAtomicSession(String[], DmtSession)}, the plugin may return
* {@code null} to indicate that the specified lock type is not supported.
* In this case the DmtAdmin may call
* {@link #openReadOnlySession(String[], DmtSession)} to start a read-only
* plugin session, which can be used as long as there are no write operations on
* the nodes handled by this plugin.
*
* The {@code sessionRoot} parameter of each method is a String array
* containing the segments of the URI pointing to the root of the session. This
* is an absolute path, so the first segment is always ".". Special
* characters appear escaped in the segments.
*
*
* @version $Id: 9c832c44be569dfd63ef66eb5a40bae7b283b81f $
*/
public interface DataPlugin {
/**
* This method is called to signal the start of a read-only session when the
* first reference is made within a {@code DmtSession} to a node
* which is handled by this plugin. Session information is given as it is
* needed for sending alerts back from the plugin.
*
* The plugin can assume that there are no writing sessions open on any
* subtree that has any overlap with the subtree of this session.
*
* @param sessionRoot the path to the subtree which is accessed in the
* current session, must not be {@code null}
* @param session the session from which this plugin instance is accessed,
* must not be {@code null}
* @return a plugin session capable of executing read operations
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code sessionRoot}
* points to a non-existing node
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if some underlying operation failed because of
* lack of permissions
*/
ReadableDataSession openReadOnlySession(String[] sessionRoot,
DmtSession session) throws DmtException;
/**
* This method is called to signal the start of a non-atomic read-write
* session when the first reference is made within a {@code DmtSession}
* to a node which is handled by this plugin. Session information is given
* as it is needed for sending alerts back from the plugin.
*
* The plugin can assume that there are no other sessions open on any
* subtree that has any overlap with the subtree of this session.
*
* @param sessionRoot the path to the subtree which is locked in the current
* session, must not be {@code null}
* @param session the session from which this plugin instance is accessed,
* must not be {@code null}
* @return a plugin session capable of executing read-write operations, or
* {@code null} if the plugin does not support non-atomic
* read-write sessions
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code sessionRoot}
* points to a non-existing node
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if some underlying operation failed because of
* lack of permissions
*/
ReadWriteDataSession openReadWriteSession(String[] sessionRoot,
DmtSession session) throws DmtException;
/**
* This method is called to signal the start of an atomic read-write session
* when the first reference is made within a {@code DmtSession} to a
* node which is handled by this plugin. Session information is given as it
* is needed for sending alerts back from the plugin.
*
* The plugin can assume that there are no other sessions open on any
* subtree that has any overlap with the subtree of this session.
*
* @param sessionRoot the path to the subtree which is locked in the current
* session, must not be {@code null}
* @param session the session from which this plugin instance is accessed,
* must not be {@code null}
* @return a plugin session capable of executing read-write operations in an
* atomic block, or {@code null} if the plugin does not
* support atomic read-write sessions
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code sessionRoot}
* points to a non-existing node
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if some underlying operation failed because of
* lack of permissions
*/
TransactionalDataSession openAtomicSession(String[] sessionRoot,
DmtSession session) throws DmtException;
}
osgi-compendium-4.3.0/src/info/dmtree/spi/ExecPlugin.java 0000644 0001750 0001750 00000006447 11564442770 023241 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.spi;
import info.dmtree.DmtException;
import info.dmtree.DmtSession;
/**
* An implementation of this interface takes the responsibility of handling node
* execute requests requests in a subtree of the DMT.
*
* In an OSGi environment such implementations should be registered at the OSGi
* service registry specifying the list of root node URIs in a
* {@code String} array in the {@code execRootURIs} registration
* parameter.
*
* @version $Id: c79828948f304c0f55a835af04f01d5861adeb1d $
*/
public interface ExecPlugin {
/**
* Execute the given node with the given data. This operation corresponds to
* the EXEC command in OMA DM.
*
* The semantics of an execute operation and the data parameter it takes
* depends on the definition of the managed object on which the command is
* issued. Session information is given as it is needed for sending alerts
* back from the plugin. If a correlation ID is specified, it should be used
* as the {@code correlator} parameter for alerts sent in response to
* this execute operation.
*
* The {@code nodePath} parameter contains an array of path segments
* identifying the node to be executed in the subtree of this plugin. This
* is an absolute path, so the first segment is always ".".
* Special characters appear escaped in the segments.
*
* @param session a reference to the session in which the operation was
* issued, must not be {@code null}
* @param nodePath the absolute path of the node to be executed, must not be
* {@code null}
* @param correlator an identifier to associate this operation with any
* alerts sent in response to it, can be {@code null}
* @param data the parameter of the execute operation, can be
* {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if the node does not exist and
* the plugin does not allow executing unexisting nodes
*
{@code METADATA_MISMATCH} if the command failed
* because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @see DmtSession#execute(String, String)
* @see DmtSession#execute(String, String, String)
*/
void execute(DmtSession session, String[] nodePath, String correlator,
String data) throws DmtException;
}
osgi-compendium-4.3.0/src/info/dmtree/spi/ReadableDataSession.java 0000644 0001750 0001750 00000044012 11466514064 025016 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.spi;
import info.dmtree.DmtData;
import info.dmtree.DmtException;
import info.dmtree.MetaNode;
import java.util.Date;
/**
* Provides read-only access to the part of the tree handled by the plugin that
* created this session.
*
* Since the {@link ReadWriteDataSession} and {@link TransactionalDataSession}
* interfaces inherit from this interface, some of the method descriptions do
* not apply for an instance that is only a {@code ReadableDataSession}.
* For example, the {@link #close} method description also contains information
* about its behaviour when invoked as part of a transactional session.
*
* The {@code nodePath} parameters appearing in this interface always
* contain an array of path segments identifying a node in the subtree of this
* plugin. This parameter contains an absolute path, so the first segment is
* always ".". Special characters appear escaped in the segments.
*
* Error handling
*
* When a tree access command is called on the DmtAdmin service, it must perform
* an extensive set of checks on the parameters and the authority of the caller
* before delegating the call to a plugin. Therefore plugins can take certain
* circumstances for granted: that the path is valid and is within the subtree
* of the plugin and the session, the command can be applied to the given node
* (e.g. the target of {@code getChildNodeNames} is an interior node), etc.
* All errors described by the error codes {@link DmtException#INVALID_URI},
* {@link DmtException#URI_TOO_LONG}, {@link DmtException#PERMISSION_DENIED},
* {@link DmtException#COMMAND_NOT_ALLOWED} and
* {@link DmtException#TRANSACTION_ERROR} are fully filtered out before control
* reaches the plugin.
*
* If the plugin provides meta-data for a node, the DmtAdmin service must also
* check the constraints specified by it, as described in {@link MetaNode}. If
* the plugin does not provide meta-data, it must perform the necessary checks
* for itself and use the {@link DmtException#METADATA_MISMATCH} error code to
* indicate such discrepancies.
*
* The DmtAdmin also ensures that the targeted nodes exist before calling the
* plugin (except, of course, before the {@code isNodeUri} call). However,
* some small amount of time elapses between the check and the call, so in case
* of plugins where the node structure can change independantly from the DMT,
* the target node might disappear in that time. For example, a whole subtree
* can disappear when a Monitorable application is unregistered, which might
* happen in the middle of a DMT session accessing it. Plugins managing such
* nodes always need to check whether they still exist and throw
* {@link DmtException#NODE_NOT_FOUND} as necessary, but for more static
* subtrees there is no need for the plugin to use this error code.
*
* The plugin can use the remaining error codes as needed. If an error does not
* fit into any other category, the {@link DmtException#COMMAND_FAILED} code
* should be used.
*
* @version $Id: fdc501943df679cda179475a1f1257112d8fadfd $
*/
public interface ReadableDataSession {
/**
* Notifies the plugin that the given node has changed outside the scope of
* the plugin, therefore the Version and Timestamp properties must be
* updated (if supported). This method is needed because the ACL property of
* a node is managed by the DmtAdmin instead of the plugin. The DmtAdmin
* must call this method whenever the ACL property of a node changes.
*
* @param nodePath the absolute path of the node that has changed
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
*/
void nodeChanged(String[] nodePath) throws DmtException;
/**
* Closes a session. This method is always called when the session ends for
* any reason: if the session is closed, if a fatal error occurs in any
* method, or if any error occurs during commit or rollback. In case the
* session was invalidated due to an exception during commit or rollback, it
* is guaranteed that no methods are called on the plugin until it is
* closed. In case the session was invalidated due to a fatal exception in
* one of the tree manipulation methods, only the rollback method is called
* before this (and only in atomic sessions).
*
* This method should not perform any data manipulation, only cleanup
* operations. In non-atomic read-write sessions the data manipulation
* should be done instantly during each tree operation, while in atomic
* sessions the {@code DmtAdmin} always calls
* {@link TransactionalDataSession#commit} automatically before the session
* is actually closed.
*
* @throws DmtException with the error code {@code COMMAND_FAILED} if
* the plugin failed to close for any reason
*/
void close() throws DmtException;
/**
* Get the list of children names of a node. The returned array contains the
* names - not the URIs - of the immediate children nodes of the given node.
* The returned child names must be mangled ({@link info.dmtree.Uri#mangle(String)}).
* The returned array may contain {@code null} entries, but these are
* removed by the DmtAdmin before returning it to the client.
*
* @param nodePath the absolute path of the node
* @return the list of child node names as a string array or an empty string
* array if the node has no children
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
String[] getChildNodeNames(String[] nodePath) throws DmtException;
/**
* Get the meta data which describes a given node. Meta data can be only
* inspected, it can not be changed.
*
* Meta data support by plugins is an optional feature. It can be used, for
* example, when a data plugin is implemented on top of a data store or
* another API that has their own metadata, such as a relational database,
* in order to avoid metadata duplication and inconsistency. The meta data
* specific to the plugin returned by this method is complemented by meta
* data from the DmtAdmin before returning it to the client. If there are
* differences in the meta data elements known by the plugin and the
* {@code DmtAdmin} then the plugin specific elements take
* precedence.
*
* Note, that a node does not have to exist for having meta-data associated
* with it. This method may provide meta-data for any node that can possibly
* exist in the tree (any node defined by the Management Object provided by
* the plugin). For nodes that are not defined, a {@code DmtException}
* may be thrown with the {@code NODE_NOT_FOUND} error code. To allow
* easier implementation of plugins that do not provide meta-data, it is
* allowed to return {@code null} for any node, regardless of whether
* it is defined or not.
*
* @param nodePath the absolute path of the node
* @return a MetaNode which describes meta data information, can be
* {@code null} if there is no meta data available for the
* given node
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodeUri}
* points to a node that is not defined in the tree (see above)
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
MetaNode getMetaNode(String[] nodePath) throws DmtException;
/**
* Get the size of the data in a leaf node. The value to return depends on
* the format of the data in the node, see the description of the
* {@link DmtData#getSize()} method for the definition of node size for each
* format.
*
* @param nodePath the absolute path of the leaf node
* @return the size of the data in the node
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the Size property is
* not supported by the plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtData#getSize
*/
int getNodeSize(String[] nodePath) throws DmtException;
/**
* Get the timestamp when the node was last modified.
*
* @param nodePath the absolute path of the node
* @return the timestamp of the last modification
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the Timestamp
* property is not supported by the plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
Date getNodeTimestamp(String[] nodePath) throws DmtException;
/**
* Get the title of a node. There might be no title property set for a node.
*
* @param nodePath the absolute path of the node
* @return the title of the node, or {@code null} if the node has no
* title
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the Title property
* is not supported by the plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
String getNodeTitle(String[] nodePath) throws DmtException;
/**
* Get the type of a node. The type of leaf node is the MIME type of the
* data it contains. The type of an interior node is a URI identifying a DDF
* document; a {@code null} type means that there is no DDF document
* overriding the tree structure defined by the ancestors.
*
* @param nodePath the absolute path of the node
* @return the type of the node, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
String getNodeType(String[] nodePath) throws DmtException;
/**
* Check whether the specified path corresponds to a valid node in the DMT.
*
* @param nodePath the absolute path to check
* @return true if the given node exists in the DMT
*/
boolean isNodeUri(String[] nodePath);
/**
* Tells whether a node is a leaf or an interior node of the DMT.
*
* @param nodePath the absolute path of the node
* @return true if the given node is a leaf node
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
boolean isLeafNode(String[] nodePath) throws DmtException;
/**
* Get the data contained in a leaf or interior node.
*
* @param nodePath the absolute path of the node to retrieve
* @return the data of the leaf node, must not be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the specified node is
* an interior node and does not support Java object values
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
DmtData getNodeValue(String[] nodePath) throws DmtException;
/**
* Get the version of a node. The version can not be set, it is calculated
* automatically by the device. It is incremented modulo 0x10000 at every
* modification of the value or any other property of the node, for both
* leaf and interior nodes. When a node is created the initial value is 0.
*
* @param nodePath the absolute path of the node
* @return the version of the node
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the information could
* not be retrieved because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the Version property
* is not supported by the plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
int getNodeVersion(String[] nodePath) throws DmtException;
}
osgi-compendium-4.3.0/src/info/dmtree/spi/packageinfo 0000644 0001750 0001750 00000000014 11405717676 022511 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/info/dmtree/spi/TransactionalDataSession.java 0000644 0001750 0001750 00000006743 11466514064 026132 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.spi;
import info.dmtree.DmtException;
/**
* Provides atomic read-write access to the part of the tree handled by the
* plugin that created this session.
*
* @version $Id: fa17127995f9e650baec161d4d767a9aef510cb9 $
*/
public interface TransactionalDataSession extends ReadWriteDataSession {
/**
* Commits a series of DMT operations issued in the current atomic session
* since the last transaction boundary. Transaction boundaries are the
* creation of this object that starts the session, and all subsequent
* {@link #commit} and {@link #rollback} calls.
*
* This method can fail even if all operations were successful. This can
* happen due to some multi-node semantic constraints defined by a specific
* implementation. For example, node A can be required to always have
* children A/B, A/C and A/D. If this condition is broken when
* {@code commit()} is executed, the method will fail, and throw a
* {@code METADATA_MISMATCH} exception.
*
* In many cases the tree is not the only way to manage a given part of the
* system. It may happen that while modifying some nodes in an atomic
* session, the underlying settings are modified parallelly outside the
* scope of the DMT. If this is detected during commit, an exception with
* the code {@code CONCURRENT_ACCESS} is thrown.
*
* @throws DmtException with the following possible error codes
*
*
{@code METADATA_MISMATCH} if the operation failed
* because of meta-data restrictions
*
{@code CONCURRENT_ACCESS} if it is detected that some
* modification has been made outside the scope of the DMT to the
* nodes affected in the session's operations
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
void commit() throws DmtException;
/**
* Rolls back a series of DMT operations issued in the current atomic
* session since the last transaction boundary. Transaction boundaries are
* the creation of this object that starts the session, and all subsequent
* {@link #commit} and {@link #rollback} calls.
*
* @throws DmtException with the error code {@code ROLLBACK_FAILED}
* in case the rollback did not succeed
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
*/
void rollback() throws DmtException;
}
osgi-compendium-4.3.0/src/info/dmtree/spi/ReadWriteDataSession.java 0000644 0001750 0001750 00000035741 11466514064 025216 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package info.dmtree.spi;
import info.dmtree.DmtData;
import info.dmtree.DmtException;
import info.dmtree.DmtSession;
import info.dmtree.MetaNode;
/**
* Provides non-atomic read-write access to the part of the tree handled by the
* plugin that created this session.
*
* The {@code nodePath} parameters appearing in this interface always
* contain an array of path segments identifying a node in the subtree of this
* plugin. This parameter contains an absolute path, so the first segment is
* always ".". Special characters appear escaped in the segments.
*
* Error handling
*
* When a tree manipulation command is called on the DmtAdmin service, it must
* perform an extensive set of checks on the parameters and the authority of the
* caller before delegating the call to a plugin. Therefore plugins can take
* certain circumstances for granted: that the path is valid and is within the
* subtree of the plugin and the session, the command can be applied to the
* given node (e.g. the target of {@code setNodeValue} is a leaf node),
* etc. All errors described by the error codes {@link DmtException#INVALID_URI}, {@link DmtException#URI_TOO_LONG}, {@link DmtException#PERMISSION_DENIED},
* {@link DmtException#COMMAND_NOT_ALLOWED} and
* {@link DmtException#TRANSACTION_ERROR} are fully filtered out before control
* reaches the plugin.
*
* If the plugin provides meta-data for a node, the DmtAdmin service must also
* check the constraints specified by it, as described in {@link MetaNode}. If
* the plugin does not provide meta-data, it must perform the necessary checks
* for itself and use the {@link DmtException#METADATA_MISMATCH} error code to
* indicate such discrepancies.
*
* The DmtAdmin also ensures that the targeted nodes exist before calling the
* plugin (or that they do not exist, in case of node creation). However, some
* small amount of time elapses between the check and the call, so in case of
* plugins where the node structure can change independantly from the DMT, the
* target node might appear/disappear in that time. For example, a whole subtree
* can disappear when a Monitorable application is unregistered, which might
* happen in the middle of a DMT session accessing it. Plugins managing such
* nodes always need to check the existance or non-existance of nodes and throw
* {@link DmtException#NODE_NOT_FOUND} or
* {@link DmtException#NODE_ALREADY_EXISTS} as necessary, but for more static
* subtrees there is no need for the plugin to use these error codes.
*
* The plugin can use the remaining error codes as needed. If an error does not
* fit into any other category, the {@link DmtException#COMMAND_FAILED} code
* should be used.
*
* @version $Id: fbde6c1121240b239e8a907c6427eeb242e78322 $
*/
public interface ReadWriteDataSession extends ReadableDataSession {
/**
* Create a copy of a node or a whole subtree. Beside the structure and
* values of the nodes, most properties managed by the plugin must also be
* copied, with the exception of the Timestamp and Version properties.
*
* @param nodePath an absolute path specifying the node or the root of a
* subtree to be copied
* @param newNodePath the absolute path of the new node or root of a subtree
* @param recursive {@code false} if only a single node is copied,
* {@code true} if the whole subtree is copied
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node, or if {@code newNodePath}
* points to a node that cannot exist in the tree
*
{@code NODE_ALREADY_EXISTS} if
* {@code newNodePath} points to a node that already exists
*
{@code METADATA_MISMATCH} if the node could not be
* copied because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the copy operation
* is not supported by the plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#copy(String, String, boolean)
*/
void copy(String[] nodePath, String[] newNodePath, boolean recursive)
throws DmtException;
/**
* Create an interior node with a given type. The type of interior node, if
* specified, is a URI identifying a DDF document.
*
* @param nodePath the absolute path of the node to create
* @param type the type URI of the interior node, can be {@code null}
* if no node type is defined
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a node that cannot exist in the tree
*
{@code NODE_ALREADY_EXISTS} if {@code nodeUri}
* points to a node that already exists
*
{@code METADATA_MISMATCH} if the node could not be
* created because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#createInteriorNode(String)
* @see DmtSession#createInteriorNode(String, String)
*/
void createInteriorNode(String[] nodePath, String type) throws DmtException;
/**
* Create a leaf node with a given value and MIME type. If the specified
* value or MIME type is {@code null}, their default values must be
* taken.
*
* @param nodePath the absolute path of the node to create
* @param value the value to be given to the new node, can be
* {@code null}
* @param mimeType the MIME type to be given to the new node, can be
* {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a node that cannot exist in the tree
*
{@code NODE_ALREADY_EXISTS} if {@code nodePath}
* points to a node that already exists
*
{@code METADATA_MISMATCH} if the node could not be
* created because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#createLeafNode(String)
* @see DmtSession#createLeafNode(String, DmtData)
* @see DmtSession#createLeafNode(String, DmtData, String)
*/
void createLeafNode(String[] nodePath, DmtData value, String mimeType)
throws DmtException;
/**
* Delete the given node. Deleting interior nodes is recursive, the whole
* subtree under the given node is deleted.
*
* @param nodePath the absolute path of the node to delete
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the node could not be
* deleted because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#deleteNode(String)
*/
void deleteNode(String[] nodePath) throws DmtException;
/**
* Rename a node. This operation only changes the name of the node (updating
* the timestamp and version properties if they are supported), the value
* and the other properties are not changed. The new name of the node must
* be provided, the new path is constructed from the base of the old path
* and the given name.
*
* @param nodePath the absolute path of the node to rename
* @param newName the new name property of the node
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node, or if the new node is not defined
* in the tree
*
{@code NODE_ALREADY_EXISTS} if there already exists a
* sibling of {@code nodePath} with the name
* {@code newName}
*
{@code METADATA_MISMATCH} if the node could not be
* renamed because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#renameNode(String, String)
*/
void renameNode(String[] nodePath, String newName) throws DmtException;
/**
* Set the title property of a node. The length of the title is guaranteed
* not to exceed the limit of 255 bytes in UTF-8 encoding.
*
* @param nodePath the absolute path of the node
* @param title the title text of the node, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the title could not be
* set because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the Title property
* is not supported by the plugin
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#setNodeTitle(String, String)
*/
void setNodeTitle(String[] nodePath, String title) throws DmtException;
/**
* Set the type of a node. The type of leaf node is the MIME type of the
* data it contains. The type of an interior node is a URI identifying a DDF
* document.
*
* For interior nodes, the {@code null} type should remove the
* reference (if any) to a DDF document overriding the tree structure
* defined by the ancestors. For leaf nodes, it requests that the default
* MIME type is used for the given node.
*
* @param nodePath the absolute path of the node
* @param type the type of the node, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the type could not be
* set because of meta-data restrictions
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#setNodeType(String, String)
*/
void setNodeType(String[] nodePath, String type) throws DmtException;
/**
* Set the value of a leaf or interior node. The format of the node is
* contained in the {@code DmtData} object. For interior nodes, the
* format is {@code FORMAT_NODE}, while for leaf nodes this format is
* never used.
*
* If the specified value is {@code null}, the default value must be
* taken; if there is no default value, a {@code DmtException} with
* error code {@code METADATA_MISMATCH} must be thrown.
*
* @param nodePath the absolute path of the node
* @param data the data to be set, can be {@code null}
* @throws DmtException with the following possible error codes:
*
*
{@code NODE_NOT_FOUND} if {@code nodePath}
* points to a non-existing node
*
{@code METADATA_MISMATCH} if the value could not be
* set because of meta-data restrictions
*
{@code FEATURE_NOT_SUPPORTED} if the specified node is
* an interior node and does not support Java object values
*
{@code DATA_STORE_FAILURE} if an error occurred while
* accessing the data store
*
{@code COMMAND_FAILED} if some unspecified error is
* encountered while attempting to complete the command
*
* @throws SecurityException if the caller does not have the necessary
* permissions to execute the underlying management operation
* @see DmtSession#setNodeValue(String, DmtData)
*/
void setNodeValue(String[] nodePath, DmtData data) throws DmtException;
}
osgi-compendium-4.3.0/src/org/ 0000755 0001750 0001750 00000000000 11632153414 016067 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/ 0000755 0001750 0001750 00000000000 11632153414 017030 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/application/ 0000755 0001750 0001750 00000000000 11632153414 021333 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/application/package-info.java 0000644 0001750 0001750 00000002516 11466514064 024535 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Foreign Application Package Version 1.0.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.application; version="[1.0,1.1)"}
*
* @version $Id: cd35b66cfa49a385a5650be5ceecad454d65e7b9 $
*/
package org.osgi.application;
osgi-compendium-4.3.0/src/org/osgi/application/Framework.java 0000644 0001750 0001750 00000004770 11466514064 024152 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.application;
import java.util.Hashtable;
/**
* Using this class, OSGi-aware applications can obtain their
* {@link ApplicationContext}.
*
* @version $Id: 68f0c39e8c8c0ea02ae2c20154bba8bf1e6ba7bc $
*/
public final class Framework {
private Framework() { }
private static Hashtable appContextHash;
/**
* This method needs an argument, an object that represents the application instance.
* An application consists of a set of object, however there is a single object, which
* is used by the corresponding application container to manage the lifecycle on the
* application instance. The lifetime of this object equals the lifetime of
* the application instance; therefore, it is suitable to represent the instance.
*
* The returned {@link ApplicationContext} object is singleton for the
* specified application instance. Subsequent calls to this method with the same
* application instance must return the same context object
*
* @param applicationInstance is the activator object of an application instance
* @throws java.lang.NullPointerException If {@code applicationInstance}
* is {@code null}
* @throws java.lang.IllegalArgumentException if called with an object that is not
* the activator object of an application.
* @return the {@link ApplicationContext} of the specified application instance.
*/
public static ApplicationContext getApplicationContext(Object applicationInstance) {
if( applicationInstance == null )
throw new NullPointerException( "Instance cannot be null!" );
ApplicationContext appContext = (ApplicationContext)appContextHash.get( applicationInstance );
if( appContext == null )
throw new IllegalArgumentException( "ApplicationContext not found!" );
return appContext;
}
}
osgi-compendium-4.3.0/src/org/osgi/application/ApplicationServiceEvent.java 0000644 0001750 0001750 00000006504 11466514064 027000 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.application;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceReference;
/**
* An event from the Framework describing a service lifecycle change.
*
* {@code ApplicationServiceEvent} objects are delivered to a
* {@code ApplicationServiceListener} objects when a change occurs in this service's
* lifecycle. The delivery of an {@code ApplicationServiceEvent} is
* always triggered by a {@link org.osgi.framework.ServiceEvent}.
* {@code ApplicationServiceEvent} extends the content of {@code ServiceEvent}
* with the service object the event is referring to as applications has no means to
* find the corresponding service object for a {@link org.osgi.framework.ServiceReference}.
* A type code is used to identify the event type for future
* extendability. The available type codes are defined in {@link org.osgi.framework.ServiceEvent}.
*
*
* OSGi Alliance reserves the right to extend the set of types.
*
* @see org.osgi.framework.ServiceEvent
* @see ApplicationServiceListener
*
* @version $Id: bf3629f6023fe5a3897d1cfdcd441630187c3909 $
*/
public class ApplicationServiceEvent extends ServiceEvent {
private static final long serialVersionUID = -4762149286971897323L;
final Object serviceObject;
/**
* Creates a new application service event object.
*
* @param type The event type. Available type codes are defines in
* {@link org.osgi.framework.ServiceEvent}
* @param reference A {@code ServiceReference} object to the service
* that had a lifecycle change. This reference will be used as the {@code source}
* in the {@link java.util.EventObject} baseclass, therefore, it must not be
* null.
* @param serviceObject The service object bound to this application instance. It can
* be {@code null} if this application is not bound to this service yet.
* @throws IllegalArgumentException if the specified {@code reference} is null.
*/
public ApplicationServiceEvent(int type, ServiceReference reference, Object serviceObject) {
super(type, reference);
this.serviceObject = serviceObject;
}
/**
* This method returns the service object of this service bound to the listener
* application instance. A service object becomes bound to the application when it
* first obtains a service object reference to that service by calling the
* {@code ApplicationContext.locateService} or {@code locateServices}
* methods. If the application is not bound to the service yet, this method returns
* {@code null}.
*
* @return the service object bound to the listener application or {@code null}
* if it isn't bound to this service yet.
*/
public Object getServiceObject() {
return this.serviceObject;
}
}
osgi-compendium-4.3.0/src/org/osgi/application/packageinfo 0000644 0001750 0001750 00000000014 11405717702 023524 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/org/osgi/application/ApplicationContext.java 0000644 0001750 0001750 00000041530 11632147274 026020 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.application;
import java.util.Dictionary;
import java.util.Map;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
/**
* {@code ApplicationContext} is the access point for an OSGi-aware application
* to the features of the OSGi Service Platform. Each application instance will
* have its own {@code ApplicationContext} instance, which will not be reused
* after destroying the corresponding application instance.
*
* Application instances can obtain their {@code ApplicationContext} using the
* {@link Framework#getApplicationContext(Object)} method.
*
* The lifecycle of an {@code ApplicationContext} instance is bound to the
* lifecycle of the corresponding application instance. The
* {@code ApplicationContext} becomes available when the application is started
* and it is invalidated when the application instance is stopped (i.e. the
* "stop" method of the application activator object returned). All method calls
* (except {@link #getApplicationId()} and {@link #getInstanceId()}) to an
* invalidated context object result an {@code IllegalStateException}.
*
* @see org.osgi.application.Framework
*
* @version $Id: b86dd158983b7a8aafa2a8023d76ef15b3e68125 $
*/
public interface ApplicationContext {
/**
* Adds the specified {@link ApplicationServiceListener} object to this context
* application instance's list of listeners. The specified {@code referenceName} is a
* reference name specified in the descriptor of the corresponding application. The registered
* {@code listener} will only receive the {@link ApplicationServiceEvent}s related to the referred service.
*
* If the {@code listener} was already added, calling this method will overwrite the previous
* registration.
*
*
* @param listener
* The {@link org.osgi.application.ApplicationServiceListener} to be added. It must
* not be {@code null}
* @param referenceName the reference name of a service from the descriptor of the corresponding
* application. It must not be {@code null}.
* @throws java.lang.IllegalStateException
* If this context application instance has stopped.
* @throws java.lang.NullPointerException If {@code listener} or {@code referenceName}
* is {@code null}
* @throws java.lang.IllegalArgumentException If there is no service in the
* application descriptor with the specified {@code referenceName}.
*/
public void addServiceListener(ApplicationServiceListener listener, String referenceName) throws java.lang.IllegalArgumentException;
/**
* Adds the specified {@link ApplicationServiceListener} object to this context
* application instance's list of listeners. The {@code referenceNames} parameter is an
* array of reference name specified in the descriptor of the corresponding application. The registered
* {@code listener} will only receive the {@link ApplicationServiceEvent}s related to the referred
* services.
*
* If the {@code listener} was already added, calling this method will overwrite the previous
* registration.
*
*
* @param listener
* The {@link org.osgi.application.ApplicationServiceListener} to be added. It must not
* be {@code null}
* @param referenceNames and array of service reference names from the descriptor of the corresponding
* application. It must not be {@code null} and it must not be empty.
* @throws java.lang.IllegalStateException
* If this context application instance has stopped.
* @throws java.lang.NullPointerException If {@code listener} or {@code referenceNames}
* is {@code null}
* @throws java.lang.IllegalArgumentException If {@code referenceNames} array is empty or it
* contains unknown references
*/
public void addServiceListener(ApplicationServiceListener listener, String[] referenceNames) throws java.lang.IllegalArgumentException;
/**
* Removes the specified {@link org.osgi.application.ApplicationServiceListener} object from this
* context application instances's list of listeners.
*
* If {@code listener} is not contained in this context application
* instance's list of listeners, this method does nothing.
*
* @param listener
* The {@link org.osgi.application.ApplicationServiceListener} object to be removed.
* @throws java.lang.IllegalStateException
* If this context application instance has stopped.
*/
public void removeServiceListener(ApplicationServiceListener listener);
/**
* This method returns the identifier of the corresponding application
* instance. This identifier is guaranteed to be unique within the scope of
* the device.
*
* Note: this method can safely be called on an invalid
* {@code ApplicationContext} as well.
*
* @see org.osgi.service.application.ApplicationHandle#getInstanceId()
*
* @return the unique identifier of the corresponding application instance
*/
public String getInstanceId();
/**
* This method return the identifier of the corresponding application type. This identifier
* is the same for the different instances of the same application but it is different for
* different application type.
*
* Note: this method can safely be called on an invalid
* {@code ApplicationContext} as well.
*
* @see org.osgi.service.application.ApplicationDescriptor#getApplicationId()
*
* @return the identifier of the application type.
*/
public String getApplicationId();
/**
* This method returns the service object for the specified
* {@code referenceName}. If the cardinality of the reference is
* 0..n or 1..n and multiple services are bound to the reference, the
* service with the highest ranking (as specified in its
* {@link org.osgi.framework.Constants#SERVICE_RANKING} property) is returned. If there
* is a tie in ranking, the service with the lowest service ID (as specified
* in its {@link org.osgi.framework.Constants#SERVICE_ID} property); that is, the
* service that was registered first is returned.
*
* @param referenceName
* The name of a reference as specified in a reference element in
* this context applications's description. It must not be {@code null}
* @return A service object for the referenced service or {@code null}
* if the reference cardinality is 0..1 or 0..n and no bound service
* is available.
* @throws java.lang.NullPointerException If {@code referenceName} is {@code null}.
* @throws java.lang.IllegalArgumentException If there is no service in the
* application descriptor with the specified {@code referenceName}.
* @throws java.lang.IllegalStateException
* If this context application instance has stopped.
*/
public Object locateService(String referenceName);
/**
* This method returns the service objects for the specified
* {@code referenceName}.
*
* @param referenceName
* The name of a reference as specified in a reference element in
* this context applications's description. It must not be
* {@code null}.
* @return An array of service object for the referenced service or
* {@code null} if the reference cardinality is 0..1 or 0..n
* and no bound service is available.
* @throws java.lang.NullPointerException If {@code referenceName} is {@code null}.
* @throws java.lang.IllegalArgumentException If there is no service in the
* application descriptor with the specified {@code referenceName}.
* @throws java.lang.IllegalStateException
* If this context application instance has stopped.
*/
public Object[] locateServices(String referenceName);
/**
* Returns the startup parameters specified when calling the
* {@code org.osgi.service.application.ApplicationDescriptor#launch(Map)}
* method.
*
* Startup arguments can be specified as name, value pairs. The name must be
* of type {@link java.lang.String}, which must not be {@code null} or empty
* {@link java.lang.String} ({@code ""}), the value can be any object
* including {@code null}.
*
* @return a {@link java.util.Map} containing the startup arguments. It can
* be {@code null}.
* @throws java.lang.IllegalStateException If this context application
* instance has stopped.
*/
public Map getStartupParameters();
/**
* Application can query the service properties of a service object
* it is bound to. Application gets bound to a service object when
* it first obtains a reference to the service by calling
* {@code locateService} or {@code locateServices} methods.
*
* @param serviceObject A service object the application is bound to.
* It must not be null.
* @return The service properties associated with the specified service
* object.
* @throws NullPointerException if the specified {@code serviceObject}
* is {@code null}
* @throws IllegalArgumentException if the application is not
* bound to the specified service object or it is not a service
* object at all.
* @throws java.lang.IllegalStateException
* If this context application instance has stopped.
*/
public Map getServiceProperties(Object serviceObject);
/**
* Registers the specified service object with the specified properties
* under the specified class names into the Framework. A
* {@link org.osgi.framework.ServiceRegistration} object is returned. The
* {@link org.osgi.framework.ServiceRegistration} object is for the private
* use of the application registering the service and should not be shared
* with other applications. The registering application is defined to be the
* context application. Bundles can locate the service by using either the
* {@link org.osgi.framework.BundleContext#getServiceReferences(String, String)}
* or {@link org.osgi.framework.BundleContext#getServiceReference(String)}
* method. Other applications can locate this service by using
* {@link #locateService(String)} or {@link #locateServices(String)} method,
* if they declared their dependence on the registered service.
*
*
* An application can register a service object that implements the
* {@link org.osgi.framework.ServiceFactory} interface to have more
* flexibility in providing service objects to other applications or
* bundles.
*
*
* The following steps are required to register a service:
*
*
If {@code service} is not a {@code ServiceFactory}, an
* {@code IllegalArgumentException} is thrown if {@code service} is not an
* {@code instanceof} all the classes named.
*
The Framework adds these service properties to the specified
* {@code Dictionary} (which may be {@code null}): a property named
* {@link org.osgi.framework.Constants#SERVICE_ID} identifying the
* registration number of the service and a property named
* {@link org.osgi.framework.Constants#OBJECTCLASS} containing all the
* specified classes. If any of these properties have already been specified
* by the registering bundle, their values will be overwritten by the
* Framework.
*
The service is added to the Framework service registry and may now be
* used by others.
*
A service event of type
* {@link org.osgi.framework.ServiceEvent#REGISTERED} is fired. This event
* triggers the corresponding {@link ApplicationServiceEvent} to be
* delivered to the applications that registered the appropriate listener.
*
A {@code ServiceRegistration} object for this registration is
* returned.
*
*
* @param clazzes The class names under which the service can be located.
* The class names in this array will be stored in the service's
* properties under the key
* {@link org.osgi.framework.Constants#OBJECTCLASS}. This parameter
* must not be {@code null}.
* @param service The service object or a {@code ServiceFactory} object.
* @param properties The properties for this service. The keys in the
* properties object must all be {@code String} objects. See
* {@link org.osgi.framework.Constants} for a list of standard
* service property keys. Changes should not be made to this object
* after calling this method. To update the service's properties the
* {@link org.osgi.framework.ServiceRegistration#setProperties(Dictionary)}
* method must be called. The set of properties may be {@code null}
* if the service has no properties.
*
* @return A {@link org.osgi.framework.ServiceRegistration} object for use
* by the application registering the service to update the
* service's properties or to unregister the service.
*
* @throws java.lang.IllegalArgumentException If one of the following is
* true:
*
*
{@code service} is {@code null}.
{@code service} is not a
* {@code ServiceFactory} object and is not an instance of all the
* named classes in {@code clazzes}.
{@code properties} contains
* case variants of the same key name.
*
* @throws NullPointerException if {@code clazzes} is {@code null}
*
* @throws java.lang.SecurityException If the caller does not have the
* {@code ServicePermission} to register the service for all the
* named classes and the Java Runtime Environment supports
* permissions.
*
* @throws java.lang.IllegalStateException If this ApplicationContext is no
* longer valid.
*
* @see org.osgi.framework.BundleContext#registerService(java.lang.String[],
* java.lang.Object, java.util.Dictionary)
* @see org.osgi.framework.ServiceRegistration
* @see org.osgi.framework.ServiceFactory
*/
public ServiceRegistration registerService(String[] clazzes,
Object service, Dictionary properties);
/**
* Registers the specified service object with the specified properties
* under the specified class name with the Framework.
*
*
* This method is otherwise identical to
* {@link #registerService(java.lang.String[], java.lang.Object,
* java.util.Dictionary)} and is provided as a convenience when
* {@code service} will only be registered under a single class name.
* Note that even in this case the value of the service's
* {@link Constants#OBJECTCLASS} property will be an array of strings,
* rather than just a single string.
*
* @param clazz The class name under which the service can be located. It
* must not be {@code null}
* @param service The service object or a {@code ServiceFactory}
* object.
* @param properties The properties for this service.
*
* @return A {@code ServiceRegistration} object for use by the application
* registering the service to update the service's properties or to
* unregister the service.
*
* @throws java.lang.IllegalArgumentException If one of the following is
* true:
*
*
{@code service} is {@code null}.
*
{@code service} is not a {@code ServiceFactory}
* object and is not an instance of the named class in
* {@code clazz}.
*
{@code properties} contains case variants of the same
* key name.
*
* @throws NullPointerException if {@code clazz} is {@code null}
*
* @throws java.lang.SecurityException If the caller does not have the
* {@code ServicePermission} to register the service
* the named class and the Java Runtime Environment supports
* permissions.
*
* @throws java.lang.IllegalStateException If this ApplicationContext is no
* longer valid.
* @see #registerService(java.lang.String[], java.lang.Object,
* java.util.Dictionary)
*/
public ServiceRegistration registerService(String clazz, Object service,
Dictionary properties);
}
osgi-compendium-4.3.0/src/org/osgi/application/ApplicationServiceListener.java 0000644 0001750 0001750 00000005257 11466514064 027510 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.application;
import java.util.EventListener;
import org.osgi.framework.*;
/**
* An {@code ApplicationServiceEvent} listener. When a
* {@code ServiceEvent} is
* fired, it is converted to an {@code ApplictionServiceEvent}
* and it is synchronously delivered to an {@code ApplicationServiceListener}.
*
*
* {@code ApplicationServiceListener} is a listener interface that may be
* implemented by an application developer.
*
* An {@code ApplicationServiceListener} object is registered with the Framework
* using the {@code ApplicationContext.addServiceListener} method.
* {@code ApplicationServiceListener} objects are called with an
* {@code ApplicationServiceEvent} object when a service is registered, modified, or
* is in the process of unregistering.
*
*
* {@code ApplicationServiceEvent} object delivery to
* {@code ApplicationServiceListener}
* objects is filtered by the filter specified when the listener was registered.
* If the Java Runtime Environment supports permissions, then additional
* filtering is done. {@code ApplicationServiceEvent} objects are only delivered to
* the listener if the application which defines the listener object's class has the
* appropriate {@code ServicePermission} to get the service using at
* least one of the named classes the service was registered under, and the application
* specified its dependence on the corresponding service in the application metadata.
*
*
* {@code ApplicationServiceEvent} object delivery to {@code ApplicationServiceListener}
* objects is further filtered according to package sources as defined in
* {@link ServiceReference#isAssignableTo(Bundle, String)}.
*
* @version $Id: fdd38c556d5784e412d68175a59f6f83c92aa4cc $
* @see ApplicationServiceEvent
* @see ServicePermission
*/
public interface ApplicationServiceListener extends EventListener {
/**
* Receives notification that a service has had a lifecycle change.
*
* @param event The {@code ApplicationServiceEvent} object.
*/
public void serviceChanged(ApplicationServiceEvent event);
}
osgi-compendium-4.3.0/src/org/osgi/service/ 0000755 0001750 0001750 00000000000 11632153414 020470 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/log/ 0000755 0001750 0001750 00000000000 11632153414 021251 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/log/package-info.java 0000644 0001750 0001750 00000002506 11466514064 024452 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Log Service Package Version 1.3.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.service.log; version="[1.3,1.4)"}
*
* @version $Id: 5c4120fc17628d242e1641557eacb9581b08c920 $
*/
package org.osgi.service.log;
osgi-compendium-4.3.0/src/org/osgi/service/log/LogListener.java 0000644 0001750 0001750 00000003357 11466514064 024362 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.log;
import java.util.EventListener;
/**
* Subscribes to {@code LogEntry} objects from the {@code LogReaderService}.
*
*
* A {@code LogListener} object may be registered with the Log Reader Service
* using the {@code LogReaderService.addLogListener} method. After the
* listener is registered, the {@code logged} method will be called for each
* {@code LogEntry} object created. The {@code LogListener} object may be
* unregistered by calling the {@code LogReaderService.removeLogListener}
* method.
*
* @ThreadSafe
* @version $Id: 9b1ea6645e00027d03684b74745f47a42fb9ad30 $
* @see LogReaderService
* @see LogEntry
* @see LogReaderService#addLogListener(LogListener)
* @see LogReaderService#removeLogListener(LogListener)
*/
public interface LogListener extends EventListener {
/**
* Listener method called for each LogEntry object created.
*
*
* As with all event listeners, this method should return to its caller as
* soon as possible.
*
* @param entry A {@code LogEntry} object containing log information.
* @see LogEntry
*/
public void logged(LogEntry entry);
}
osgi-compendium-4.3.0/src/org/osgi/service/log/LogEntry.java 0000644 0001750 0001750 00000006770 11466514064 023700 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.log;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceReference;
/**
* Provides methods to access the information contained in an individual Log
* Service log entry.
*
*
* A {@code LogEntry} object may be acquired from the
* {@code LogReaderService.getLog} method or by registering a
* {@code LogListener} object.
*
* @ThreadSafe
* @noimplement
* @version $Id: e20fd66ff9e0264d77f7b7ea19212b305d1b3a40 $
* @see LogReaderService#getLog
* @see LogListener
*/
public interface LogEntry {
/**
* Returns the bundle that created this {@code LogEntry} object.
*
* @return The bundle that created this {@code LogEntry} object;
* {@code null} if no bundle is associated with this
* {@code LogEntry} object.
*/
public Bundle getBundle();
/**
* Returns the {@code ServiceReference} object for the service associated
* with this {@code LogEntry} object.
*
* @return {@code ServiceReference} object for the service associated
* with this {@code LogEntry} object; {@code null} if no
* {@code ServiceReference} object was provided.
*/
public ServiceReference getServiceReference();
/**
* Returns the severity level of this {@code LogEntry} object.
*
*
* This is one of the severity levels defined by the {@code LogService}
* interface.
*
* @return Severity level of this {@code LogEntry} object.
*
* @see LogService#LOG_ERROR
* @see LogService#LOG_WARNING
* @see LogService#LOG_INFO
* @see LogService#LOG_DEBUG
*/
public int getLevel();
/**
* Returns the human readable message associated with this {@code LogEntry}
* object.
*
* @return {@code String} containing the message associated with this
* {@code LogEntry} object.
*/
public String getMessage();
/**
* Returns the exception object associated with this {@code LogEntry}
* object.
*
*
* In some implementations, the returned exception may not be the original
* exception. To avoid references to a bundle defined exception class, thus
* preventing an uninstalled bundle from being garbage collected, the Log
* Service may return an exception object of an implementation defined
* Throwable subclass. The returned object will attempt to provide as much
* information as possible from the original exception object such as the
* message and stack trace.
*
* @return {@code Throwable} object of the exception associated with this
* {@code LogEntry};{@code null} if no exception is
* associated with this {@code LogEntry} object.
*/
public Throwable getException();
/**
* Returns the value of {@code currentTimeMillis()} at the time this
* {@code LogEntry} object was created.
*
* @return The system time in milliseconds when this {@code LogEntry}
* object was created.
* @see "System.currentTimeMillis()"
*/
public long getTime();
}
osgi-compendium-4.3.0/src/org/osgi/service/log/packageinfo 0000644 0001750 0001750 00000000014 11405717704 023444 0 ustar drazzib drazzib version 1.3
osgi-compendium-4.3.0/src/org/osgi/service/log/LogReaderService.java 0000644 0001750 0001750 00000006522 11466514064 025315 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.log;
import java.util.Enumeration;
/**
* Provides methods to retrieve {@code LogEntry} objects from the log.
*
* There are two ways to retrieve {@code LogEntry} objects:
*
*
The primary way to retrieve {@code LogEntry} objects is to register a
* {@code LogListener} object whose {@code LogListener.logged} method will
* be called for each entry added to the log.
*
To retrieve past {@code LogEntry} objects, the {@code getLog}
* method can be called which will return an {@code Enumeration} of all
* {@code LogEntry} objects in the log.
*
* @ThreadSafe
* @version $Id: bb22587248982a76202b77d03550515b3205f935 $
* @see LogEntry
* @see LogListener
* @see LogListener#logged(LogEntry)
*/
public interface LogReaderService {
/**
* Subscribes to {@code LogEntry} objects.
*
*
* This method registers a {@code LogListener} object with the Log Reader
* Service. The {@code LogListener.logged(LogEntry)} method will be
* called for each {@code LogEntry} object placed into the log.
*
*
* When a bundle which registers a {@code LogListener} object is stopped
* or otherwise releases the Log Reader Service, the Log Reader Service must
* remove all of the bundle's listeners.
*
*
* If this Log Reader Service's list of listeners already contains a
* listener {@code l} such that {@code (l==listener)}, this method
* does nothing.
*
* @param listener A {@code LogListener} object to register; the
* {@code LogListener} object is used to receive {@code LogEntry}
* objects.
* @see LogListener
* @see LogEntry
* @see LogListener#logged(LogEntry)
*/
public void addLogListener(LogListener listener);
/**
* Unsubscribes to {@code LogEntry} objects.
*
*
* This method unregisters a {@code LogListener} object from the Log
* Reader Service.
*
*
* If {@code listener} is not contained in this Log Reader Service's list
* of listeners, this method does nothing.
*
* @param listener A {@code LogListener} object to unregister.
* @see LogListener
*/
public void removeLogListener(LogListener listener);
/**
* Returns an {@code Enumeration} of all {@code LogEntry} objects in
* the log.
*
*
* Each element of the enumeration is a {@code LogEntry} object, ordered
* with the most recent entry first. Whether the enumeration is of all
* {@code LogEntry} objects since the Log Service was started or some
* recent past is implementation-specific. Also implementation-specific is
* whether informational and debug {@code LogEntry} objects are included
* in the enumeration.
* @return An {@code Enumeration} of all {@code LogEntry} objects in
* the log.
*/
public Enumeration getLog();
}
osgi-compendium-4.3.0/src/org/osgi/service/log/LogService.java 0000644 0001750 0001750 00000011463 11466514064 024172 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.log;
import org.osgi.framework.ServiceReference;
/**
* Provides methods for bundles to write messages to the log.
*
*
* {@code LogService} methods are provided to log messages; optionally with a
* {@code ServiceReference} object or an exception.
*
*
* Bundles must log messages in the OSGi environment with a severity level
* according to the following hierarchy:
*
* This log entry indicates the bundle or service may not be functional.
*/
public static final int LOG_ERROR = 1;
/**
* A warning message (Value 2).
*
*
* This log entry indicates a bundle or service is still functioning but may
* experience problems in the future because of the warning condition.
*/
public static final int LOG_WARNING = 2;
/**
* An informational message (Value 3).
*
*
* This log entry may be the result of any change in the bundle or service
* and does not indicate a problem.
*/
public static final int LOG_INFO = 3;
/**
* A debugging message (Value 4).
*
*
* This log entry is used for problem determination and may be irrelevant to
* anyone but the bundle developer.
*/
public static final int LOG_DEBUG = 4;
/**
* Logs a message.
*
*
* The {@code ServiceReference} field and the {@code Throwable} field
* of the {@code LogEntry} object will be set to {@code null}.
*
* @param level The severity of the message. This should be one of the
* defined log levels but may be any integer that is interpreted in a
* user defined way.
* @param message Human readable string describing the condition or
* {@code null}.
* @see #LOG_ERROR
* @see #LOG_WARNING
* @see #LOG_INFO
* @see #LOG_DEBUG
*/
public void log(int level, String message);
/**
* Logs a message with an exception.
*
*
* The {@code ServiceReference} field of the {@code LogEntry} object
* will be set to {@code null}.
*
* @param level The severity of the message. This should be one of the
* defined log levels but may be any integer that is interpreted in a
* user defined way.
* @param message The human readable string describing the condition or
* {@code null}.
* @param exception The exception that reflects the condition or
* {@code null}.
* @see #LOG_ERROR
* @see #LOG_WARNING
* @see #LOG_INFO
* @see #LOG_DEBUG
*/
public void log(int level, String message, Throwable exception);
/**
* Logs a message associated with a specific {@code ServiceReference}
* object.
*
*
* The {@code Throwable} field of the {@code LogEntry} will be set to
* {@code null}.
*
* @param sr The {@code ServiceReference} object of the service that this
* message is associated with or {@code null}.
* @param level The severity of the message. This should be one of the
* defined log levels but may be any integer that is interpreted in a
* user defined way.
* @param message Human readable string describing the condition or
* {@code null}.
* @see #LOG_ERROR
* @see #LOG_WARNING
* @see #LOG_INFO
* @see #LOG_DEBUG
*/
public void log(ServiceReference sr, int level, String message);
/**
* Logs a message with an exception associated and a
* {@code ServiceReference} object.
*
* @param sr The {@code ServiceReference} object of the service that this
* message is associated with.
* @param level The severity of the message. This should be one of the
* defined log levels but may be any integer that is interpreted in a
* user defined way.
* @param message Human readable string describing the condition or
* {@code null}.
* @param exception The exception that reflects the condition or
* {@code null}.
* @see #LOG_ERROR
* @see #LOG_WARNING
* @see #LOG_INFO
* @see #LOG_DEBUG
*/
public void log(ServiceReference sr, int level, String message,
Throwable exception);
}
osgi-compendium-4.3.0/src/org/osgi/service/jdbc/ 0000755 0001750 0001750 00000000000 11632153414 021372 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/jdbc/package-info.java 0000644 0001750 0001750 00000002512 11466514064 024570 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* JDBC Service Package Version 1.0.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.service.jdbc; version="[1.0,1.1)"}
*
* @version $Id: 411479758718416ee6810084a6b38a3f0a4b1b99 $
*/
package org.osgi.service.jdbc;
osgi-compendium-4.3.0/src/org/osgi/service/jdbc/packageinfo 0000644 0001750 0001750 00000000014 11405717704 023565 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/org/osgi/service/jdbc/DataSourceFactory.java 0000644 0001750 0001750 00000021156 11466514064 025633 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.jdbc;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
/**
* A factory for JDBC connection factories. There are 3 preferred connection
* factories for getting JDBC connections: {@code javax.sql.DataSource},
* {@code javax.sql.ConnectionPoolDataSource}, and
* {@code javax.sql.XADataSource}.
*
* DataSource providers should implement this interface and register it as an
* OSGi service with the JDBC driver class name in the
* {@link #OSGI_JDBC_DRIVER_CLASS} property.
*
* @version $Id: dc3ae0d203ac25792bdae5f5880e270904a47fb6 $
* @ThreadSafe
*/
public interface DataSourceFactory {
/**
* Service property used by a JDBC driver to declare the driver class when
* registering a JDBC DataSourceFactory service. Clients may filter or test
* this property to determine if the driver is suitable, or the desired one.
*/
public static final String OSGI_JDBC_DRIVER_CLASS = "osgi.jdbc.driver.class";
/**
* Service property used by a JDBC driver to declare the driver name when
* registering a JDBC DataSourceFactory service. Clients may filter or test
* this property to determine if the driver is suitable, or the desired one.
*/
public static final String OSGI_JDBC_DRIVER_NAME = "osgi.jdbc.driver.name";
/**
* Service property used by a JDBC driver to declare the driver version when
* registering a JDBC DataSourceFactory service. Clients may filter or test
* this property to determine if the driver is suitable, or the desired one.
*/
public static final String OSGI_JDBC_DRIVER_VERSION = "osgi.jdbc.driver.version";
/**
* The "databaseName" property that DataSource clients should supply a value
* for when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_DATABASE_NAME = "databaseName";
/**
* The "dataSourceName" property that DataSource clients should supply a
* value for when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_DATASOURCE_NAME = "dataSourceName";
/**
* The "description" property that DataSource clients should supply a value
* for when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_DESCRIPTION = "description";
/**
* The "networkProtocol" property that DataSource clients should supply a
* value for when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_NETWORK_PROTOCOL = "networkProtocol";
/**
* The "password" property that DataSource clients should supply a value for
* when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_PASSWORD = "password";
/**
* The "portNumber" property that DataSource clients should supply a value
* for when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_PORT_NUMBER = "portNumber";
/**
* The "roleName" property that DataSource clients should supply a value for
* when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_ROLE_NAME = "roleName";
/**
* The "serverName" property that DataSource clients should supply a value
* for when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_SERVER_NAME = "serverName";
/**
* The "user" property that DataSource clients should supply a value for
* when calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_USER = "user";
/**
* The "url" property that DataSource clients should supply a value for when
* calling {@link #createDataSource(Properties)}.
*/
public static final String JDBC_URL = "url";
/**
* The "initialPoolSize" property that ConnectionPoolDataSource and
* XADataSource clients may supply a value for when calling
* {@link #createConnectionPoolDataSource(Properties)} or
* {@link #createXADataSource(Properties)} on drivers that support
* this property.
*/
public static final String JDBC_INITIAL_POOL_SIZE = "initialPoolSize";
/**
* The "maxIdleTime" property that ConnectionPoolDataSource and
* XADataSource clients may supply a value for when calling
* {@link #createConnectionPoolDataSource(Properties)} or
* {@link #createXADataSource(Properties)} on drivers that support
* this property.
*/
public static final String JDBC_MAX_IDLE_TIME = "maxIdleTime";
/**
* The "maxPoolSize" property that ConnectionPoolDataSource and
* XADataSource clients may supply a value for when calling
* {@link #createConnectionPoolDataSource(Properties)} or
* {@link #createXADataSource(Properties)} on drivers that support
* this property.
*/
public static final String JDBC_MAX_POOL_SIZE = "maxPoolSize";
/**
* The "maxStatements" property that ConnectionPoolDataSource and
* XADataSource clients may supply a value for when calling
* {@link #createConnectionPoolDataSource(Properties)} or
* {@link #createXADataSource(Properties)} on drivers that support
* this property.
*/
public static final String JDBC_MAX_STATEMENTS = "maxStatements";
/**
* The "minPoolSize" property that ConnectionPoolDataSource and
* XADataSource clients may supply a value for when calling
* {@link #createConnectionPoolDataSource(Properties)} or
* {@link #createXADataSource(Properties)} on drivers that support
* this property.
*/
public static final String JDBC_MIN_POOL_SIZE = "minPoolSize";
/**
* The "propertyCycle" property that ConnectionPoolDataSource and
* XADataSource clients may supply a value for when calling
* {@link #createConnectionPoolDataSource(Properties)} or
* {@link #createXADataSource(Properties)} on drivers that support
* this property.
*/
public static final String JDBC_PROPERTY_CYCLE = "propertyCycle";
/**
* Create a new {@code DataSource} using the given properties.
*
* @param props The properties used to configure the {@code DataSource}
* . {@code null} indicates no properties. If the property
* cannot be set on the {@code DataSource} being created then a
* {@code SQLException} must be thrown.
* @return A configured {@code DataSource}.
* @throws SQLException If the {@code DataSource} cannot be created.
*/
public DataSource createDataSource(Properties props) throws SQLException;
/**
* Create a new {@code ConnectionPoolDataSource} using the given
* properties.
*
* @param props The properties used to configure the
* {@code ConnectionPoolDataSource}. {@code null} indicates
* no properties. If the property cannot be set on the
* {@code ConnectionPoolDataSource} being created then a
* {@code SQLException} must be thrown.
* @return A configured {@code ConnectionPoolDataSource}.
* @throws SQLException If the {@code ConnectionPoolDataSource} cannot
* be created.
*/
public ConnectionPoolDataSource createConnectionPoolDataSource(
Properties props) throws SQLException;
/**
* Create a new {@code XADataSource} using the given properties.
*
* @param props The properties used to configure the
* {@code XADataSource}. {@code null} indicates no
* properties. If the property cannot be set on the
* {@code XADataSource} being created then a
* {@code SQLException} must be thrown.
* @return A configured {@code XADataSource}.
* @throws SQLException If the {@code XADataSource} cannot be created.
*/
public XADataSource createXADataSource(Properties props)
throws SQLException;
/**
* Create a new {@code Driver} using the given properties.
*
* @param props The properties used to configure the {@code Driver}.
* {@code null} indicates no properties. If the property cannot
* be set on the {@code Driver} being created then a
* {@code SQLException} must be thrown.
* @return A configured {@code Driver}.
* @throws SQLException If the {@code Driver} cannot be created.
*/
public Driver createDriver(Properties props) throws SQLException;
}
osgi-compendium-4.3.0/src/org/osgi/service/device/ 0000755 0001750 0001750 00000000000 11632153414 021727 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/device/package-info.java 0000644 0001750 0001750 00000002521 11466514064 025125 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Device Access Package Version 1.1.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.service.device; version="[1.1,1.2)"}
*
* @version $Id: 0c957a50efbc06eb4bb7f1c46695a757bc12e9a6 $
*/
package org.osgi.service.device;
osgi-compendium-4.3.0/src/org/osgi/service/device/Driver.java 0000644 0001750 0001750 00000010334 11632147274 024035 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.device;
import org.osgi.framework.ServiceReference;
/**
* A {@code Driver} service object must be registered by each Driver bundle
* wishing to attach to Device services provided by other drivers. For each
* newly discovered {@link Device} object, the device manager enters a bidding
* phase. The {@code Driver} object whose {@link #match(ServiceReference)}
* method bids the highest for a particular {@code Device} object will be
* instructed by the device manager to attach to the {@code Device} object.
*
* @version $Id: 8d86c732bdc1e4d50c18a237427578472e13dcbf $
* @see Device
* @see DriverLocator
* @ThreadSafe
*/
public interface Driver {
/**
* Checks whether this Driver service can be attached to the Device service.
*
* The Device service is represented by the given {@link ServiceReference}
* and returns a value indicating how well this driver can support the given
* Device service, or {@link Device#MATCH_NONE} if it cannot support the
* given Device service at all.
*
*
* The return value must be one of the possible match values defined in the
* device category definition for the given Device service, or
* {@code Device.MATCH_NONE} if the category of the Device service is
* not recognized.
*
*
* In order to make its decision, this Driver service may examine the
* properties associated with the given Device service, or may get the
* referenced service object (representing the actual physical device) to
* talk to it, as long as it ungets the service and returns the physical
* device to a normal state before this method returns.
*
*
* A Driver service must always return the same match code whenever it is
* presented with the same Device service.
*
*
* The match function is called by the device manager during the matching
* process.
*
* @param reference the {@code ServiceReference} object of the device
* to match
*
* @return value indicating how well this driver can support the given
* Device service, or {@code Device.MATCH_NONE} if it cannot
* support the Device service at all
*
* @throws java.lang.Exception if this Driver service cannot examine the
* Device service
*/
public int match(ServiceReference reference) throws Exception;
/**
* Attaches this Driver service to the Device service represented by the
* given {@code ServiceReference} object.
*
*
* A return value of {@code null} indicates that this Driver service
* has successfully attached to the given Device service. If this Driver
* service is unable to attach to the given Device service, but knows of a
* more suitable Driver service, it must return the {@code DRIVER_ID}
* of that Driver service. This allows for the implementation of referring
* drivers whose only purpose is to refer to other drivers capable of
* handling a given Device service.
*
*
* After having attached to the Device service, this driver may register the
* underlying device as a new service exposing driver-specific
* functionality.
*
*
* This method is called by the device manager.
*
* @param reference the {@code ServiceReference} object of the device
* to attach to
*
* @return {@code null} if this Driver service has successfully
* attached to the given Device service, or the
* {@code DRIVER_ID} of a more suitable driver
*
* @throws java.lang.Exception if the driver cannot attach to the given
* device and does not know of a more suitable driver
*/
public String attach(ServiceReference reference) throws Exception;
}
osgi-compendium-4.3.0/src/org/osgi/service/device/DriverSelector.java 0000644 0001750 0001750 00000004253 11466514064 025541 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.device;
import org.osgi.framework.ServiceReference;
/**
* When the device manager detects a new Device service, it calls all registered
* Driver services to determine if anyone matches the Device service. If at
* least one Driver service matches, the device manager must choose one. If
* there is a Driver Selector service registered with the Framework, the device
* manager will ask it to make the selection. If there is no Driver Selector
* service, or if it returns an invalid result, or throws an
* {@code Exception}, the device manager uses the default selection
* strategy.
*
* @version $Id: f3ab3493b4fe468954a709a5699f92244efacb0e $
* @since 1.1
* @ThreadSafe
*/
public interface DriverSelector {
/**
* Return value from {@code DriverSelector.select}, if no Driver
* service should be attached to the Device service. The value is -1.
*/
public static final int SELECT_NONE = -1;
/**
* Select one of the matching Driver services. The device manager calls this
* method if there is at least one driver bidding for a device. Only Driver
* services that have responded with nonzero (not {@link Device#MATCH_NONE})
* {@code } match values will be included in the list.
*
* @param reference the {@code ServiceReference} object of the Device
* service.
* @param matches the array of all non-zero matches.
* @return index into the array of {@code Match} objects, or
* {@code SELECT_NONE} if no Driver service should be attached
*/
public int select(ServiceReference reference, Match[] matches);
}
osgi-compendium-4.3.0/src/org/osgi/service/device/DriverLocator.java 0000644 0001750 0001750 00000004721 11466514064 025364 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.device;
import java.io.IOException;
import java.io.InputStream;
import java.util.Dictionary;
/**
* A Driver Locator service can find and load device driver bundles given a
* property set. Each driver is represented by a unique {@code DRIVER_ID}.
*
* Driver Locator services provide the mechanism for dynamically downloading new
* device driver bundles into an OSGi environment. They are supplied by
* providers and encapsulate all provider-specific details related to the
* location and acquisition of driver bundles.
*
* @version $Id: 85498ef85f1a48248b6dc01455264b2f866022ea $
* @see Driver
* @ThreadSafe
*/
public interface DriverLocator {
/**
* Returns an array of {@code DRIVER_ID} strings of drivers capable of
* attaching to a device with the given properties.
*
*
* The property keys in the specified {@code Dictionary} objects are
* case-insensitive.
*
* @param props the properties of the device for which a driver is sought
* @return array of driver {@code DRIVER_ID} strings of drivers capable
* of attaching to a Device service with the given properties, or
* {@code null} if this Driver Locator service does not know of
* any such drivers
*/
public String[] findDrivers(Dictionary props);
/**
* Get an {@code InputStream} from which the driver bundle providing a
* driver with the giving {@code DRIVER_ID} can be installed.
*
* @param id the {@code DRIVER_ID} of the driver that needs to be
* installed.
* @return An {@code InputStream} object from which the driver bundle
* can be installed or {@code null} if the driver with the
* given ID cannot be located
* @throws java.io.IOException the input stream for the bundle cannot be
* created
*/
public InputStream loadDriver(String id) throws IOException;
}
osgi-compendium-4.3.0/src/org/osgi/service/device/Constants.java 0000644 0001750 0001750 00000005000 11466514064 024550 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.device;
/**
* This interface defines standard names for property keys associated with
* {@link Device} and {@link Driver} services.
*
*
* The values associated with these keys are of type {@code java.lang.String},
* unless otherwise stated.
*
* @noimplement
* @version $Id: 58acb0b3339b5db94bb014d32f4eeb360a394fd4 $
* @since 1.1
* @see Device
* @see Driver
*/
public interface Constants {
/**
* Property (named "DRIVER_ID") identifying a driver.
*
*
* A {@code DRIVER_ID} should start with the reversed domain name of the
* company that implemented the driver (e.g., {@code com.acme}), and
* must meet the following requirements:
*
*
*
It must be independent of the location from where it is obtained.
*
It must be independent of the {@link DriverLocator} service that
* downloaded it.
*
It must be unique.
*
It must be different for different revisions of the same driver.
*
*
*
* This property is mandatory, i.e., every {@code Driver} service must be
* registered with it.
*/
public static final String DRIVER_ID = "DRIVER_ID";
/**
* Property (named "DEVICE_CATEGORY") containing a human readable
* description of the device categories implemented by a device. This
* property is of type {@code String[]}
*
*
* Services registered with this property will be treated as devices and
* discovered by the device manager
*/
public static final String DEVICE_CATEGORY = "DEVICE_CATEGORY";
/**
* Property (named "DEVICE_SERIAL") specifying a device's serial
* number.
*/
public static final String DEVICE_SERIAL = "DEVICE_SERIAL";
/**
* Property (named "DEVICE_DESCRIPTION") containing a human
* readable string describing the actual hardware device.
*/
public static final String DEVICE_DESCRIPTION = "DEVICE_DESCRIPTION";
}
osgi-compendium-4.3.0/src/org/osgi/service/device/packageinfo 0000644 0001750 0001750 00000000014 11402155312 024106 0 ustar drazzib drazzib version 1.1
osgi-compendium-4.3.0/src/org/osgi/service/device/Device.java 0000644 0001750 0001750 00000004271 11632147274 024004 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.device;
import org.osgi.framework.ServiceReference;
/**
*
* Interface for identifying device services.
*
*
* A service must implement this interface or use the
* {@link Constants#DEVICE_CATEGORY} registration property to indicate that it
* is a device. Any services implementing this interface or registered with the
* {@code DEVICE_CATEGORY} property will be discovered by the device manager.
*
*
* Device services implementing this interface give the device manager the
* opportunity to indicate to the device that no drivers were found that could
* (further) refine it. In this case, the device manager calls the
* {@link #noDriverFound()} method on the {@code Device} object.
*
*
* Specialized device implementations will extend this interface by adding
* methods appropriate to their device category to it.
*
* @version $Id: 40e60d46b721a8b94408fdb97844904acec60cdf $
* @see Driver
* @ThreadSafe
*/
public interface Device {
/**
* Return value from {@link Driver#match(ServiceReference)} indicating that
* the driver cannot refine the device presented to it by the device
* manager.
*
* The value is zero.
*/
public static final int MATCH_NONE = 0;
/**
* Indicates to this {@code Device} object that the device manager has
* failed to attach any drivers to it.
*
*
* If this {@code Device} object can be configured differently, the
* driver that registered this {@code Device} object may unregister it
* and register a different Device service instead.
*/
public void noDriverFound();
}
osgi-compendium-4.3.0/src/org/osgi/service/device/Match.java 0000644 0001750 0001750 00000002522 11632147274 023636 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2001, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.device;
import org.osgi.framework.ServiceReference;
/**
* Instances of {@code Match} are used in the
* {@link DriverSelector#select(ServiceReference, Match[])} method to identify
* Driver services matching a Device service.
*
* @ThreadSafe
* @noimplement
* @version $Id: e5c5171200f54046030901c55a7ca484ca217c35 $
* @since 1.1
* @see DriverSelector
*/
public interface Match {
/**
* Return the reference to a Driver service.
*
* @return {@code ServiceReference} object to a Driver service.
*/
public ServiceReference getDriver();
/**
* Return the match value of this object.
*
* @return the match value returned by this Driver service.
*/
public int getMatchValue();
}
osgi-compendium-4.3.0/src/org/osgi/service/prefs/ 0000755 0001750 0001750 00000000000 11632153414 021607 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/prefs/package-info.java 0000644 0001750 0001750 00000002524 11466514064 025010 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Preferences Service Package Version 1.1.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.service.prefs; version="[1.1,1.2)"}
*
* @version $Id: 38fc16ac58979748bcd6cf394b0d6d71aa374515 $
*/
package org.osgi.service.prefs;
osgi-compendium-4.3.0/src/org/osgi/service/prefs/Preferences.java 0000644 0001750 0001750 00000100610 11632147274 024720 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2001, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.prefs;
/**
* A node in a hierarchical collection of preference data.
*
*
* This interface allows applications to store and retrieve user and system
* preference data. This data is stored persistently in an
* implementation-dependent backing store. Typical implementations include flat
* files, OS-specific registries, directory servers and SQL databases.
*
*
* For each bundle, there is a separate tree of nodes for each user, and one for
* system preferences. The precise description of "user" and "system" will vary
* from one bundle to another. Typical information stored in the user preference
* tree might include font choice, and color choice for a bundle which interacts
* with the user via a servlet. Typical information stored in the system
* preference tree might include installation data, or things like high score
* information for a game program.
*
*
* Nodes in a preference tree are named in a similar fashion to directories in a
* hierarchical file system. Every node in a preference tree has a node name
* (which is not necessarily unique), a unique absolute path name ,
* and a path name relative to each ancestor including itself.
*
*
* The root node has a node name of the empty {@code String} object ("").
* Every other node has an arbitrary node name, specified at the time it is
* created. The only restrictions on this name are that it cannot be the empty
* string, and it cannot contain the slash character ('/').
*
*
* The root node has an absolute path name of {@code "/"}. Children of the
* root node have absolute path names of {@code "/" + } <node name>
* . All other nodes have absolute path names of <parent's absolute
* path name> {@code + "/" + } <node name> . Note that
* all absolute path names begin with the slash character.
*
*
* A node n 's path name relative to its ancestor a is simply the
* string that must be appended to a 's absolute path name in order to
* form n 's absolute path name, with the initial slash character (if
* present) removed. Note that:
*
*
No relative path names begin with the slash character.
*
Every node's path name relative to itself is the empty string.
*
Every node's path name relative to its parent is its node name (except
* for the root node, which does not have a parent).
*
Every node's path name relative to the root is its absolute path name
* with the initial slash character removed.
*
*
*
* Note finally that:
*
*
No path name contains multiple consecutive slash characters.
*
No path name with the exception of the root's absolute path name end in
* the slash character.
*
Any string that conforms to these two rules is a valid path name.
*
*
*
* Each {@code Preference} node has zero or more properties associated with
* it, where a property consists of a name and a value. The bundle writer is
* free to choose any appropriate names for properties. Their values can be of
* type {@code String},{@code long},{@code int},{@code boolean},
* {@code byte[]},{@code float}, or {@code double} but they can
* always be accessed as if they were {@code String} objects.
*
*
* All node name and property name comparisons are case-sensitive.
*
*
* All of the methods that modify preference data are permitted to operate
* asynchronously; they may return immediately, and changes will eventually
* propagate to the persistent backing store, with an implementation-dependent
* delay. The {@code flush} method may be used to synchronously force updates
* to the backing store.
*
*
* Implementations must automatically attempt to flush to the backing store any
* pending updates for a bundle's preferences when the bundle is stopped or
* otherwise ungets the Preferences Service.
*
*
* The methods in this class may be invoked concurrently by multiple threads in
* a single Java Virtual Machine (JVM) without the need for external
* synchronization, and the results will be equivalent to some serial execution.
* If this class is used concurrently by multiple JVMs that store their
* preference data in the same backing store, the data store will not be
* corrupted, but no other guarantees are made concerning the consistency of the
* preference data.
*
* @noimplement
* @version $Id: 4560e5f4056911d618ca257084befd972c16bbd7 $
*/
public interface Preferences {
/**
* Associates the specified value with the specified key in this node.
*
* @param key key with which the specified value is to be associated.
* @param value value to be associated with the specified key.
* @throws NullPointerException if {@code key} or {@code value} is
* {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public void put(String key, String value);
/**
* Returns the value associated with the specified {@code key} in this
* node. Returns the specified default if there is no value associated with
* the {@code key}, or the backing store is inaccessible.
*
* @param key key whose associated value is to be returned.
* @param def the value to be returned in the event that this node has no
* value associated with {@code key} or the backing store is
* inaccessible.
* @return the value associated with {@code key}, or {@code def} if
* no value is associated with {@code key}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @throws NullPointerException if {@code key} is {@code null}. (A
* {@code null} default is permitted.)
*/
public String get(String key, String def);
/**
* Removes the value associated with the specified {@code key} in this
* node, if any.
*
* @param key key whose mapping is to be removed from this node.
* @see #get(String,String)
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public void remove(String key);
/**
* Removes all of the properties (key-value associations) in this node. This
* call has no effect on any descendants of this node.
*
* @throws BackingStoreException if this operation cannot be completed due
* to a failure in the backing store, or inability to communicate
* with it.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #remove(String)
*/
public void clear() throws BackingStoreException;
/**
* Associates a {@code String} object representing the specified {@code int}
* value with the specified {@code key} in this node. The associated string
* is the one that would be returned if the {@code int} value were passed to
* {@code Integer.toString(int)}. This method is intended for use in
* conjunction with {@link #getInt(String, int)} method.
*
*
* Implementor's note: it is not necessary that the property value
* be represented by a {@code String} object in the backing store. If the
* backing store supports integer values, it is not unreasonable to use
* them. This implementation detail is not visible through the
* {@code Preferences} API, which allows the value to be read as an
* {@code int} (with {@code getInt} or a {@code String} (with {@code get})
* type.
*
* @param key key with which the string form of value is to be associated.
* @param value {@code value} whose string form is to be associated with
* {@code key}.
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #getInt(String,int)
*/
public void putInt(String key, int value);
/**
* Returns the {@code int} value represented by the {@code String} object
* associated with the specified {@code key} in this node. The
* {@code String} object is converted to an {@code int} as by
* {@code Integer.parseInt(String)}. Returns the specified default if there
* is no value associated with the {@code key}, the backing store is
* inaccessible, or if {@code Integer.parseInt(String)} would throw a
* {@code NumberFormatException} if the associated {@code value} were
* passed. This method is intended for use in conjunction with the
* {@link #putInt(String, int)} method.
*
* @param key key whose associated value is to be returned as an {@code int}
* .
* @param def the value to be returned in the event that this node has no
* value associated with {@code key} or the associated value cannot
* be interpreted as an {@code int} or the backing store is
* inaccessible.
* @return the {@code int} value represented by the {@code String} object
* associated with {@code key} in this node, or {@code def} if the
* associated value does not exist or cannot be interpreted as an
* {@code int} type.
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #putInt(String,int)
* @see #get(String,String)
*/
public int getInt(String key, int def);
/**
* Associates a {@code String} object representing the specified
* {@code long} value with the specified {@code key} in this node. The
* associated {@code String} object is the one that would be returned if the
* {@code long} value were passed to {@code Long.toString(long)}. This
* method is intended for use in conjunction with the
* {@link #getLong(String, long)} method.
*
*
* Implementor's note: it is not necessary that the {@code value} be
* represented by a {@code String} type in the backing store. If the backing
* store supports {@code long} values, it is not unreasonable to use them.
* This implementation detail is not visible through the {@code Preferences}
* API, which allows the value to be read as a {@code long} (with
* {@code getLong} or a {@code String} (with {@code get}) type.
*
* @param key {@code key} with which the string form of {@code value} is to
* be associated.
* @param value {@code value} whose string form is to be associated with
* {@code key}.
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #getLong(String,long)
*/
public void putLong(String key, long value);
/**
* Returns the {@code long} value represented by the {@code String} object
* associated with the specified {@code key} in this node. The
* {@code String} object is converted to a {@code long} as by
* {@code Long.parseLong(String)}. Returns the specified default if there is
* no value associated with the {@code key}, the backing store is
* inaccessible, or if {@code Long.parseLong(String)} would throw a
* {@code NumberFormatException} if the associated {@code value} were
* passed. This method is intended for use in conjunction with the
* {@link #putLong(String, long)} method.
*
* @param key {@code key} whose associated value is to be returned as a
* {@code long} value.
* @param def the value to be returned in the event that this node has no
* value associated with {@code key} or the associated value cannot
* be interpreted as a {@code long} type or the backing store is
* inaccessible.
* @return the {@code long} value represented by the {@code String} object
* associated with {@code key} in this node, or {@code def} if the
* associated value does not exist or cannot be interpreted as a
* {@code long} type.
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #putLong(String,long)
* @see #get(String,String)
*/
public long getLong(String key, long def);
/**
* Associates a {@code String} object representing the specified
* {@code boolean} value with the specified key in this node. The associated
* string is "true" if the value is {@code true}, and "false" if it is
* {@code false}. This method is intended for use in conjunction with the
* {@link #getBoolean(String, boolean)} method.
*
*
* Implementor's note: it is not necessary that the value be
* represented by a string in the backing store. If the backing store
* supports {@code boolean} values, it is not unreasonable to use them. This
* implementation detail is not visible through the {@code Preferences
* } API, which
* allows the value to be read as a {@code boolean} (with {@code getBoolean}
* ) or a {@code String} (with {@code get}) type.
*
* @param key {@code key} with which the string form of value is to be
* associated.
* @param value value whose string form is to be associated with {@code key}
* .
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #getBoolean(String,boolean)
* @see #get(String,String)
*/
public void putBoolean(String key, boolean value);
/**
* Returns the {@code boolean} value represented by the {@code String}
* object associated with the specified {@code key} in this node. Valid
* strings are "true", which represents {@code true}, and "false", which
* represents {@code false}. Case is ignored, so, for example, "TRUE" and
* "False" are also valid. This method is intended for use in conjunction
* with the {@link #putBoolean(String, boolean)} method.
*
*
* Returns the specified default if there is no value associated with the
* {@code key}, the backing store is inaccessible, or if the associated
* value is something other than "true" or "false", ignoring case.
*
* @param key {@code key} whose associated value is to be returned as a
* {@code boolean}.
* @param def the value to be returned in the event that this node has no
* value associated with {@code key} or the associated value cannot
* be interpreted as a {@code boolean} or the backing store is
* inaccessible.
* @return the {@code boolean} value represented by the {@code String}
* object associated with {@code key} in this node, or {@code null}
* if the associated value does not exist or cannot be interpreted
* as a {@code boolean}.
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #get(String,String)
* @see #putBoolean(String,boolean)
*/
public boolean getBoolean(String key, boolean def);
/**
* Associates a {@code String} object representing the specified
* {@code float} value with the specified {@code key} in this node. The
* associated {@code String} object is the one that would be returned if the
* {@code float} value were passed to {@code Float.toString(float)}. This
* method is intended for use in conjunction with the
* {@link #getFloat(String, float)} method.
*
*
* Implementor's note: it is not necessary that the value be
* represented by a string in the backing store. If the backing store
* supports {@code float} values, it is not unreasonable to use them. This
* implementation detail is not visible through the {@code Preferences
* } API, which
* allows the value to be read as a {@code float} (with {@code getFloat}) or
* a {@code String} (with {@code get}) type.
*
* @param key {@code key} with which the string form of value is to be
* associated.
* @param value value whose string form is to be associated with {@code key}
* .
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #getFloat(String,float)
*/
public void putFloat(String key, float value);
/**
* Returns the float {@code value} represented by the {@code String} object
* associated with the specified {@code key} in this node. The
* {@code String} object is converted to a {@code float} value as by
* {@code Float.parseFloat(String)}. Returns the specified default if there
* is no value associated with the {@code key}, the backing store is
* inaccessible, or if {@code Float.parseFloat(String)} would throw a
* {@code NumberFormatException} if the associated value were passed. This
* method is intended for use in conjunction with the
* {@link #putFloat(String, float)} method.
*
* @param key {@code key} whose associated value is to be returned as a
* {@code float} value.
* @param def the value to be returned in the event that this node has no
* value associated with {@code key} or the associated value cannot
* be interpreted as a {@code float} type or the backing store is
* inaccessible.
* @return the {@code float} value represented by the string associated with
* {@code key} in this node, or {@code def} if the associated value
* does not exist or cannot be interpreted as a {@code float} type.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @throws NullPointerException if {@code key} is {@code null}.
* @see #putFloat(String,float)
* @see #get(String,String)
*/
public float getFloat(String key, float def);
/**
* Associates a {@code String} object representing the specified
* {@code double} value with the specified {@code key} in this node. The
* associated {@code String} object is the one that would be returned if the
* {@code double} value were passed to {@code Double.toString(double)}. This
* method is intended for use in conjunction with the
* {@link #getDouble(String, double)} method
*
*
* Implementor's note: it is not necessary that the value be
* represented by a string in the backing store. If the backing store
* supports {@code double} values, it is not unreasonable to use them. This
* implementation detail is not visible through the {@code Preferences
* } API, which
* allows the value to be read as a {@code double} (with {@code getDouble})
* or a {@code String} (with {@code get}) type.
*
* @param key {@code key} with which the string form of value is to be
* associated.
* @param value value whose string form is to be associated with {@code key}
* .
* @throws NullPointerException if {@code key} is {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #getDouble(String,double)
*/
public void putDouble(String key, double value);
/**
* Returns the {@code double} value represented by the {@code String}
* object associated with the specified {@code key} in this node. The
* {@code String} object is converted to a {@code double} value as by
* {@code Double.parseDouble(String)}. Returns the specified default if
* there is no value associated with the {@code key}, the backing store
* is inaccessible, or if {@code Double.parseDouble(String)} would throw
* a {@code NumberFormatException} if the associated value were passed.
* This method is intended for use in conjunction with the
* {@link #putDouble} method.
*
* @param key {@code key} whose associated value is to be returned as a
* {@code double} value.
* @param def the value to be returned in the event that this node has no
* value associated with {@code key} or the associated value
* cannot be interpreted as a {@code double} type or the backing
* store is inaccessible.
* @return the {@code double} value represented by the {@code String}
* object associated with {@code key} in this node, or
* {@code def} if the associated value does not exist or cannot
* be interpreted as a {@code double} type.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the the {@link #removeNode()} method.
* @throws NullPointerException if {@code key} is {@code null}.
* @see #putDouble(String,double)
* @see #get(String,String)
*/
public double getDouble(String key, double def);
/**
* Associates a {@code String} object representing the specified
* {@code byte[]} with the specified {@code key} in this node. The
* associated {@code String} object the Base64 encoding of the
* {@code byte[]}, as defined in RFC 2045 , Section 6.8,
* with one minor change: the string will consist solely of characters from
* the Base64 Alphabet ; it will not contain any newline characters.
* This method is intended for use in conjunction with the
* {@link #getByteArray(String, byte[])} method.
*
*
* Implementor's note: it is not necessary that the value be
* represented by a {@code String} type in the backing store. If the backing
* store supports {@code byte[]} values, it is not unreasonable to use them.
* This implementation detail is not visible through the {@code Preferences}
* API, which allows the value to be read as an a {@code byte[]} object
* (with {@code getByteArray}) or a {@code String} object (with {@code get}
* ).
*
* @param key {@code key} with which the string form of {@code value} is to
* be associated.
* @param value {@code value} whose string form is to be associated with
* {@code key}.
* @throws NullPointerException if {@code key} or {@code value} is
* {@code null}.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #getByteArray(String,byte[])
* @see #get(String,String)
*/
public void putByteArray(String key, byte[] value);
/**
* Returns the {@code byte[]} value represented by the {@code String} object
* associated with the specified {@code key} in this node. Valid
* {@code String} objects are Base64 encoded binary data, as defined
* in RFC 2045 , Section
* 6.8, with one minor change: the string must consist solely of characters
* from the Base64 Alphabet ; no newline characters or extraneous
* characters are permitted. This method is intended for use in conjunction
* with the {@link #putByteArray(String, byte[])} method.
*
*
* Returns the specified default if there is no value associated with the
* {@code key}, the backing store is inaccessible, or if the associated
* value is not a valid Base64 encoded byte array (as defined above).
*
* @param key {@code key} whose associated value is to be returned as a
* {@code byte[]} object.
* @param def the value to be returned in the event that this node has no
* value associated with {@code key} or the associated value cannot
* be interpreted as a {@code byte[]} type, or the backing store is
* inaccessible.
* @return the {@code byte[]} value represented by the {@code String} object
* associated with {@code key} in this node, or {@code def} if the
* associated value does not exist or cannot be interpreted as a
* {@code byte[]}.
* @throws NullPointerException if {@code key} is {@code null}. (A
* {@code null} value for {@code def} is permitted.)
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #get(String,String)
* @see #putByteArray(String,byte[])
*/
public byte[] getByteArray(String key, byte[] def);
/**
* Returns all of the keys that have an associated value in this node. (The
* returned array will be of size zero if this node has no preferences and
* not {@code null}!)
*
* @return an array of the keys that have an associated value in this node.
* @throws BackingStoreException if this operation cannot be completed due
* to a failure in the backing store, or inability to communicate
* with it.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public String[] keys() throws BackingStoreException;
/**
* Returns the names of the children of this node. (The returned array will
* be of size zero if this node has no children and not {@code null}!)
*
* @return the names of the children of this node.
* @throws BackingStoreException if this operation cannot be completed due
* to a failure in the backing store, or inability to communicate
* with it.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public String[] childrenNames() throws BackingStoreException;
/**
* Returns the parent of this node, or {@code null} if this is the root.
*
* @return the parent of this node.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public Preferences parent();
/**
* Returns a named {@code Preferences} object (node), creating it and any
* of its ancestors if they do not already exist. Accepts a relative or
* absolute pathname. Absolute pathnames (which begin with {@code '/'})
* are interpreted relative to the root of this node. Relative pathnames
* (which begin with any character other than {@code '/'}) are
* interpreted relative to this node itself. The empty string ({@code ""})
* is a valid relative pathname, referring to this node itself.
*
*
* If the returned node did not exist prior to this call, this node and any
* ancestors that were created by this call are not guaranteed to become
* persistent until the {@code flush} method is called on the returned
* node (or one of its descendants).
*
* @param pathName the path name of the {@code Preferences} object to
* return.
* @return the specified {@code Preferences} object.
* @throws IllegalArgumentException if the path name is invalid.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @throws NullPointerException if path name is {@code null}.
* @see #flush()
*/
public Preferences node(String pathName);
/**
* Returns true if the named node exists. Accepts a relative or absolute
* pathname. Absolute pathnames (which begin with {@code '/'}) are
* interpreted relative to the root of this node. Relative pathnames (which
* begin with any character other than {@code '/'}) are interpreted
* relative to this node itself. The pathname {@code ""} is valid, and
* refers to this node itself.
*
*
* If this node (or an ancestor) has already been removed with the
* {@link #removeNode()} method, it is legal to invoke this method,
* but only with the pathname {@code ""}; the invocation will return
* {@code false}. Thus, the idiom {@code p.nodeExists("")} may be
* used to test whether {@code p} has been removed.
*
* @param pathName the path name of the node whose existence is to be
* checked.
* @return true if the specified node exists.
* @throws BackingStoreException if this operation cannot be completed due
* to a failure in the backing store, or inability to communicate
* with it.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method and
* {@code pathname} is not the empty string ({@code ""}).
* @throws IllegalArgumentException if the path name is invalid (i.e., it
* contains multiple consecutive slash characters, or ends with a
* slash character and is more than one character long).
*/
public boolean nodeExists(String pathName)
throws BackingStoreException;
/**
* Removes this node and all of its descendants, invalidating any properties
* contained in the removed nodes. Once a node has been removed, attempting
* any method other than {@code name()},{@code absolutePath()} or
* {@code nodeExists("")} on the corresponding {@code Preferences}
* instance will fail with an {@code IllegalStateException}. (The
* methods defined on {@code Object} can still be invoked on a node after
* it has been removed; they will not throw {@code IllegalStateException}.)
*
*
* The removal is not guaranteed to be persistent until the {@code flush}
* method is called on the parent of this node.
*
* @throws IllegalStateException if this node (or an ancestor) has already
* been removed with the {@link #removeNode()} method.
* @throws BackingStoreException if this operation cannot be completed due
* to a failure in the backing store, or inability to communicate
* with it.
* @see #flush()
*/
public void removeNode() throws BackingStoreException;
/**
* Returns this node's name, relative to its parent.
*
* @return this node's name, relative to its parent.
*/
public String name();
/**
* Returns this node's absolute path name. Note that:
*
*
Root node - The path name of the root node is {@code "/"}.
*
Slash at end - Path names other than that of the root node may not
* end in slash ({@code '/'}).
*
Unusual names -{@code "."} and {@code ".."} have no
* special significance in path names.
*
Illegal names - The only illegal path names are those that contain
* multiple consecutive slashes, or that end in slash and are not the root.
*
*
* @return this node's absolute path name.
*/
public String absolutePath();
/**
* Forces any changes in the contents of this node and its descendants to
* the persistent store.
*
*
* Once this method returns successfully, it is safe to assume that all
* changes made in the subtree rooted at this node prior to the method
* invocation have become permanent.
*
*
* Implementations are free to flush changes into the persistent store at
* any time. They do not need to wait for this method to be called.
*
*
* When a flush occurs on a newly created node, it is made persistent, as
* are any ancestors (and descendants) that have yet to be made persistent.
* Note however that any properties value changes in ancestors are not
* guaranteed to be made persistent.
*
* @throws BackingStoreException if this operation cannot be completed due
* to a failure in the backing store, or inability to communicate
* with it.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #sync()
*/
public void flush() throws BackingStoreException;
/**
* Ensures that future reads from this node and its descendants reflect any
* changes that were committed to the persistent store (from any VM) prior
* to the {@code sync} invocation. As a side-effect, forces any changes
* in the contents of this node and its descendants to the persistent store,
* as if the {@code flush} method had been invoked on this node.
*
* @throws BackingStoreException if this operation cannot be completed due
* to a failure in the backing store, or inability to communicate
* with it.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @see #flush()
*/
public void sync() throws BackingStoreException;
}
osgi-compendium-4.3.0/src/org/osgi/service/prefs/packageinfo 0000644 0001750 0001750 00000000016 11405717704 024004 0 ustar drazzib drazzib version 1.1.1
osgi-compendium-4.3.0/src/org/osgi/service/prefs/BackingStoreException.java 0000644 0001750 0001750 00000004315 11466514064 026716 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.prefs;
/**
* Thrown to indicate that a preferences operation could not complete because of
* a failure in the backing store, or a failure to contact the backing store.
*
* @version $Id: 86f6e3cc926b2ea3875e000e90b0700a75f2a7c7 $
*/
public class BackingStoreException extends Exception {
static final long serialVersionUID = -1415637364122829574L;
/**
* Constructs a {@code BackingStoreException} with the specified detail
* message.
*
* @param message The detail message.
*/
public BackingStoreException(String message) {
super(message);
}
/**
* Constructs a {@code BackingStoreException} with the specified detail
* message.
*
* @param message The detail message.
* @param cause The cause of the exception. May be {@code null}.
* @since 1.1
*/
public BackingStoreException(String message, Throwable cause) {
super(message, cause);
}
/**
* Returns the cause of this exception or {@code null} if no cause was
* set.
*
* @return The cause of this exception or {@code null} if no cause was
* set.
* @since 1.1
*/
public Throwable getCause() {
return super.getCause();
}
/**
* Initializes the cause of this exception to the specified value.
*
* @param cause The cause of this exception.
* @return This exception.
* @throws IllegalArgumentException If the specified cause is this
* exception.
* @throws IllegalStateException If the cause of this exception has already
* been set.
* @since 1.1
*/
public Throwable initCause(Throwable cause) {
return super.initCause(cause);
}
}
osgi-compendium-4.3.0/src/org/osgi/service/prefs/PreferencesService.java 0000644 0001750 0001750 00000003473 11466514064 026252 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.prefs;
/**
* The Preferences Service.
*
*
* Each bundle using this service has its own set of preference trees: one for
* system preferences, and one for each user.
*
*
* A {@code PreferencesService} object is specific to the bundle which
* obtained it from the service registry. If a bundle wishes to allow another
* bundle to access its preferences, it should pass its
* {@code PreferencesService} object to that bundle.
*
* @noimplement
* @version $Id: bcb430ac769863b4239575c1edeedc23fc5ab097 $
*/
public interface PreferencesService {
/**
* Returns the root system node for the calling bundle.
*
* @return The root system node for the calling bundle.
*/
public Preferences getSystemPreferences();
/**
* Returns the root node for the specified user and the calling bundle.
*
* @param name The user for which to return the preference root node.
* @return The root node for the specified user and the calling bundle.
*/
public Preferences getUserPreferences(String name);
/**
* Returns the names of users for which node trees exist.
*
* @return The names of users for which node trees exist.
*/
public String[] getUsers();
}
osgi-compendium-4.3.0/src/org/osgi/service/component/ 0000755 0001750 0001750 00000000000 11632153414 022472 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/component/ComponentException.java 0000644 0001750 0001750 00000004433 11466514064 027171 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component;
/**
* Unchecked exception which may be thrown by the Service Component Runtime.
*
* @version $Id: ce00b5bdbe563ef48a1e76cfc6ce88ce2e13298b $
*/
public class ComponentException extends RuntimeException {
static final long serialVersionUID = -7438212656298726924L;
/**
* Construct a new ComponentException with the specified message and cause.
*
* @param message The message for the exception.
* @param cause The cause of the exception. May be {@code null}.
*/
public ComponentException(String message, Throwable cause) {
super(message, cause);
}
/**
* Construct a new ComponentException with the specified message.
*
* @param message The message for the exception.
*/
public ComponentException(String message) {
super(message);
}
/**
* Construct a new ComponentException with the specified cause.
*
* @param cause The cause of the exception. May be {@code null}.
*/
public ComponentException(Throwable cause) {
super(cause);
}
/**
* Returns the cause of this exception or {@code null} if no cause was
* set.
*
* @return The cause of this exception or {@code null} if no cause was
* set.
*/
public Throwable getCause() {
return super.getCause();
}
/**
* Initializes the cause of this exception to the specified value.
*
* @param cause The cause of this exception.
* @return This exception.
* @throws IllegalArgumentException If the specified cause is this
* exception.
* @throws IllegalStateException If the cause of this exception has already
* been set.
*/
public Throwable initCause(Throwable cause) {
return super.initCause(cause);
}
}
osgi-compendium-4.3.0/src/org/osgi/service/component/package-info.java 0000644 0001750 0001750 00000002536 11466514064 025676 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Service Component Package Version 1.1.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.service.component; version="[1.1,1.2)"}
*
* @version $Id: b9d67bb6dc2a108f89d826771b56d7b3a67b3e9b $
*/
package org.osgi.service.component;
osgi-compendium-4.3.0/src/org/osgi/service/component/ComponentContext.java 0000644 0001750 0001750 00000017355 11466514064 026666 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component;
import java.util.Dictionary;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* A Component Context object is used by a component instance to interact with
* its execution context including locating services by reference name. Each
* component instance has a unique Component Context.
*
*
* A component instance may have an activate method. If a component instance has
* a suitable and accessible activate method, this method will be called when a
* component configuration is activated. If the activate method takes a
* {@code ComponentContext} argument, it will be passed the component
* instance's Component Context object. If the activate method takes a
* {@code BundleContext} argument, it will be passed the component
* instance's Bundle Context object. If the activate method takes a
* {@code Map} argument, it will be passed an unmodifiable Map containing
* the component properties.
*
*
* A component instance may have a deactivate method. If a component instance
* has a suitable and accessible deactivate method, this method will be called
* when the component configuration is deactivated. If the deactivate method
* takes a {@code ComponentContext} argument, it will be passed the
* component instance's Component Context object. If the deactivate method takes
* a {@code BundleContext} argument, it will be passed the component
* instance's Bundle Context object. If the deactivate method takes a
* {@code Map} argument, it will be passed an unmodifiable Map containing
* the component properties. If the deactivate method takes an {@code int}
* or {@code Integer} argument, it will be passed the reason code for the
* component instance's deactivation.
*
* @ThreadSafe
* @noimplement
* @version $Id: 78c996676c92ad2d2457f75337b3d97a18c88e5d $
*/
public interface ComponentContext {
/**
* Returns the component properties for this Component Context.
*
* @return The properties for this Component Context. The Dictionary is read
* only and cannot be modified.
*/
public Dictionary getProperties();
/**
* Returns the service object for the specified reference name.
*
*
* If the cardinality of the reference is {@code 0..n} or
* {@code 1..n} and multiple services are bound to the reference, the
* service with the highest ranking (as specified in its
* {@code Constants.SERVICE_RANKING} property) is returned. If there is
* a tie in ranking, the service with the lowest service ID (as specified in
* its {@code Constants.SERVICE_ID} property); that is, the service
* that was registered first is returned.
*
* @param name The name of a reference as specified in a
* {@code reference} element in this component's description.
* @return A service object for the referenced service or {@code null}
* if the reference cardinality is {@code 0..1} or
* {@code 0..n} and no bound service is available.
* @throws ComponentException If the Service Component Runtime catches an
* exception while activating the bound service.
*/
public Object locateService(String name);
/**
* Returns the service object for the specified reference name and
* {@code ServiceReference}.
*
* @param name The name of a reference as specified in a
* {@code reference} element in this component's description.
* @param reference The {@code ServiceReference} to a bound service.
* This must be a {@code ServiceReference} provided to the
* component via the bind or unbind method for the specified
* reference name.
* @return A service object for the referenced service or {@code null}
* if the specified {@code ServiceReference} is not a bound
* service for the specified reference name.
* @throws ComponentException If the Service Component Runtime catches an
* exception while activating the bound service.
*/
public Object locateService(String name, ServiceReference reference);
/**
* Returns the service objects for the specified reference name.
*
* @param name The name of a reference as specified in a
* {@code reference} element in this component's description.
* @return An array of service objects for the referenced service or
* {@code null} if the reference cardinality is
* {@code 0..1} or {@code 0..n} and no bound service is
* available. If the reference cardinality is {@code 0..1} or
* {@code 1..1} and a bound service is available, the array
* will have exactly one element.
* @throws ComponentException If the Service Component Runtime catches an
* exception while activating a bound service.
*/
public Object[] locateServices(String name);
/**
* Returns the {@code BundleContext} of the bundle which contains this
* component.
*
* @return The {@code BundleContext} of the bundle containing this
* component.
*/
public BundleContext getBundleContext();
/**
* If the component instance is registered as a service using the
* {@code servicefactory="true"} attribute, then this method
* returns the bundle using the service provided by the component instance.
*
* This method will return {@code null} if:
*
*
The component instance is not a service, then no bundle can be using
* it as a service.
*
The component instance is a service but did not specify the
* {@code servicefactory="true"} attribute, then all bundles
* using the service provided by the component instance will share the same
* component instance.
*
The service provided by the component instance is not currently being
* used by any bundle.
*
*
* @return The bundle using the component instance as a service or
* {@code null}.
*/
public Bundle getUsingBundle();
/**
* Returns the Component Instance object for the component instance
* associated with this Component Context.
*
* @return The Component Instance object for the component instance.
*/
public ComponentInstance getComponentInstance();
/**
* Enables the specified component name. The specified component name must
* be in the same bundle as this component.
*
* @param name The name of a component or {@code null} to indicate all
* components in the bundle.
*/
public void enableComponent(String name);
/**
* Disables the specified component name. The specified component name must
* be in the same bundle as this component.
*
* @param name The name of a component.
*/
public void disableComponent(String name);
/**
* If the component instance is registered as a service using the
* {@code service} element, then this method returns the service
* reference of the service provided by this component instance.
*
* This method will return {@code null} if the component instance is
* not registered as a service.
*
* @return The {@code ServiceReference} object for the component
* instance or {@code null} if the component instance is not
* registered as a service.
*/
public ServiceReference getServiceReference();
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/ 0000755 0001750 0001750 00000000000 11632153414 025027 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/package-info.java 0000644 0001750 0001750 00000001701 11632147600 030215 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Service Component Annotations Package Version 1.0.
*
*
* This package is not used at runtime. Annotated classes are processed by
* tools to generate Component Descriptions which are used at runtime.
*
* @version $Id: 2d28d03f84156d782d6a07cf6c6b814744a6d087 $
*/
package org.osgi.service.component.annotations;
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/ReferenceCardinality.java 0000644 0001750 0001750 00000002773 11632147600 031765 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
/**
* Cardinality for the {@link Reference} annotation.
*
*
* Specifies if the reference is optional and if the component implementation
* support a single bound service or multiple bound services.
*
* @version $Id: a86f2f25880cbd49111f9d8ab8279cbd5bc6e7c1 $
*/
public enum ReferenceCardinality {
/**
* The reference is optional and unary. That is, the reference has a
* cardinality of {@code 0..1}.
*/
OPTIONAL, // 0..1
/**
* The reference is mandatory and unary. That is, the reference has a
* cardinality of {@code 1..1}.
*/
MANDATORY, // 1..1
/**
* The reference is optional and multiple. That is, the reference has a
* cardinality of {@code 0..n}.
*/
MULTIPLE, // 0..n
/**
* The reference is mandatory and multiple. That is, the reference has a
* cardinality of {@code 1..n}.
*/
AT_LEAST_ONE; // 1..n
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/ReferencePolicy.java 0000644 0001750 0001750 00000003373 11632147600 030756 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
/**
* Policy for the {@link Reference} annotation.
*
* @version $Id: 698f862af7645e7a5baf98070cfbf71223041241 $
*/
public enum ReferencePolicy {
/**
* The static policy is the most simple policy and is the default policy. A
* component instance never sees any of the dynamics. Component
* configurations are deactivated before any bound service for a reference
* having a static policy becomes unavailable. If a target service is
* available to replace the bound service which became unavailable, the
* component configuration must be reactivated and bound to the replacement
* service.
*/
STATIC,
/**
* The dynamic policy is slightly more complex since the component
* implementation must properly handle changes in the set of bound services.
* With the dynamic policy, SCR can change the set of bound services without
* deactivating a component configuration. If the component uses the event
* strategy to access services, then the component instance will be notified
* of changes in the set of bound services by calls to the bind and unbind
* methods.
*/
DYNAMIC;
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/Activate.java 0000644 0001750 0001750 00000002703 11632147600 027434 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Identify the annotated method as the {@code activate} method of a Service
* Component.
*
*
* The annotated method is the activate method of the Component.
*
*
* This annotation is not processed at runtime by a Service Component Runtime
* implementation. It must be processed by tools and used to add a Component
* Description to the bundle.
*
* @see "The activate attribute of the component element of a Component Description."
* @version $Id: b61a8aecb6d8df3d60a2e6b05e6021801b580331 $
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Activate {
// marker annotation
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/Component.java 0000644 0001750 0001750 00000013343 11632147600 027640 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Identify the annotated class as a Service Component.
*
*
* The annotated class is the implementation class of the Component.
*
*
* This annotation is not processed at runtime by a Service Component Runtime
* implementation. It must be processed by tools and used to add a Component
* Description to the bundle.
*
* @see "The component element of a Component Description."
* @version $Id: 6d6332dbb471a2bc582bf8fc9a9b7f3efd02bfc2 $
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Component {
/**
* The name of this Component.
*
*
* If not specified, the name of this Component is the fully qualified type
* name of the class being annotated.
*
* @see "The name attribute of the component element of a Component Description."
*/
String name() default "";
/**
* The types under which to register this Component as a service.
*
*
* If no service should be registered, the empty value
* {} must be specified.
*
*
* If not specified, the service types for this Component are all the
* directly implemented interfaces of the class being annotated.
*
* @see "The service element of a Component Description."
*/
Class< ? >[] service() default {};
/**
* The factory identifier of this Component. Specifying a factory identifier
* makes this Component a Factory Component.
*
*
* If not specified, the default is that this Component is not a Factory
* Component.
*
* @see "The factory attribute of the component element of a Component Description."
*/
String factory() default "";
/**
* Declares whether this Component uses the OSGi ServiceFactory concept and
* each bundle using this Component's service will receive a different
* component instance.
*
*
* If {@code true}, this Component uses the OSGi ServiceFactory concept. If
* {@code false} or not specified, this Component does not use the OSGi
* ServiceFactory concept.
*
* @see "The servicefactory attribute of the service element of a Component Description."
*/
boolean servicefactory() default false;
/**
* Declares whether this Component is enabled when the bundle containing it
* is started.
*
*
* If {@code true}, this Component is enabled. If {@code false} or not
* specified, this Component is disabled.
*
* @see "The enabled attribute of the component element of a Component Description."
*/
boolean enabled() default true;
/**
* Declares whether this Component must be immediately activated upon
* becoming satisfied or whether activation should be delayed.
*
*
* If {@code true}, this Component must be immediately activated upon
* becoming satisfied. If {@code false}, activation of this Component is
* delayed. If this property is specified, its value must be {@code false}
* if the {@link #factory} property is also specified or must be
* {@code true} if the {@link #service} property is specified with an empty
* value.
*
*
* If not specified, the default is {@code false} if the {@link #factory}
* property is specified or the {@link #service} property is not specified
* or specified with a non-empty value and {@code true} otherwise.
*
* @see "The immediate attribute of the component element of a Component Description."
*/
boolean immediate() default false;
/**
* The configuration policy of this Component.
*
*
* Controls whether component configurations must be satisfied depending on
* the presence of a corresponding Configuration object in the OSGi
* Configuration Admin service. A corresponding configuration is a
* Configuration object where the PID equals the name of the component.
*
*
* If not specified, the {@link ConfigurationPolicy#OPTIONAL OPTIONAL}
* configuration policy is used.
*
* @see "The configuration-policy attribute of the component element of a Component Description."
*/
ConfigurationPolicy configurationPolicy() default ConfigurationPolicy.OPTIONAL;
/**
* Properties for this Component.
*
*
* Each property string is specified as {@code "key=value"}. The type of the
* property value can be specified in the key as {@code key:type=value}. The
* type must be one of the property types supported by the type attribute of
* the property element of a Component Description.
*
*
* To specify a property with multiple values, use multiple key, value
* pairs. For example, {@code "foo=bar", "foo=baz"}.
*
* @see "The property element of a Component Description."
*/
String[] property() default {};
/**
* Property entries for this Component.
*
*
* Specifies the name of an entry in the bundle whose contents conform to a
* standard Java Properties File. The entry is read and processed to obtain
* the properties and their values.
*
* @see "The properties element of a Component Description."
*/
String[] properties() default {};
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/Deactivate.java 0000644 0001750 0001750 00000002713 11632147600 027746 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Identify the annotated method as the {@code deactivate} method of a Service
* Component.
*
*
* The annotated method is the deactivate method of the Component.
*
*
* This annotation is not processed at runtime by a Service Component Runtime
* implementation. It must be processed by tools and used to add a Component
* Description to the bundle.
*
* @see "The deactivate attribute of the component element of a Component Description."
* @version $Id: 397f31967ac41b758dd65190962f620bf9a86bdc $
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Deactivate {
// marker annotation
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/packageinfo 0000644 0001750 0001750 00000000014 11632147600 027214 0 ustar drazzib drazzib version 1.0
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/Reference.java 0000644 0001750 0001750 00000007176 11632147600 027603 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Identify the annotated method as a {@code bind} method of a Service
* Component.
*
*
* The annotated method is a bind method of the Component.
*
*
* This annotation is not processed at runtime by a Service Component Runtime
* implementation. It must be processed by tools and used to add a Component
* Description to the bundle.
*
* @see "The reference element of a Component Description."
* @version $Id: 4fffce54b3954d421d7f2b98962ff8e1ac7f076a $
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Reference {
/**
* The name of this reference.
*
*
* If not specified, the name of this reference is based upon the name of
* the method being annotated. If the method name begins with {@code set} or
* {@code add}, that is removed.
*
* @see "The name attribute of the reference element of a Component Description."
*/
String name() default "";
/**
* The type of the service to bind to this reference.
*
*
* If not specified, the type of the service to bind is based upon the type
* of the first argument of the method being annotated.
*
* @see "The interface attribute of the reference element of a Component Description."
*/
Class< ? > service() default Object.class;
/**
* The cardinality of the reference.
*
*
* If not specified, the reference has a
* {@link ReferenceCardinality#MANDATORY 1..1} cardinality.
*
* @see "The cardinality attribute of the reference element of a Component Description."
*/
ReferenceCardinality cardinality() default ReferenceCardinality.MANDATORY;
/**
* The policy for the reference.
*
*
* If not specified, the {@link ReferencePolicy#STATIC STATIC} reference
* policy is used.
*
* @see "The policy attribute of the reference element of a Component Description."
*/
ReferencePolicy policy() default ReferencePolicy.STATIC;
/**
* The target filter for the reference.
*
* @see "The target attribute of the reference element of a Component Description."
*/
String target() default "";
/**
* The name of the unbind method which pairs with the annotated bind method.
*
*
* To declare no unbind method, the value {@code "-"} must be used.
*
*
* If not specified, the name of the unbind method is derived from the name
* of the annotated bind method. If the annotated method name begins with
* {@code set}, that is replaced with {@code unset} to derive the unbind
* method name. If the annotated method name begins with {@code add}, that
* is replaced with {@code remove} to derive the unbind method name.
* Otherwise, {@code un} is prefixed to the annotated method name to derive
* the unbind method name.
*
* @see "The unbind attribute of the reference element of a Component Description."
*/
String unbind() default "";
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/ConfigurationPolicy.java 0000644 0001750 0001750 00000003124 11632147600 031661 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
/**
* Configuration Policy for the {@link Component} annotation.
*
*
* Controls whether component configurations must be satisfied depending on the
* presence of a corresponding Configuration object in the OSGi Configuration
* Admin service. A corresponding configuration is a Configuration object where
* the PID is the name of the component.
*
* @version $Id: 333d73c609620e0474ec143b6a9b9cba7ce271e7 $
*/
public enum ConfigurationPolicy {
/**
* Use the corresponding Configuration object if present but allow the
* component to be satisfied even if the corresponding Configuration object
* is not present.
*/
OPTIONAL,
/**
* There must be a corresponding Configuration object for the component
* configuration to become satisfied.
*/
REQUIRE,
/**
* Always allow the component configuration to be satisfied and do not use
* the corresponding Configuration object even if it is present.
*/
IGNORE;
}
osgi-compendium-4.3.0/src/org/osgi/service/component/annotations/Modified.java 0000644 0001750 0001750 00000002703 11632147600 027414 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Identify the annotated method as the {@code modified} method of a Service
* Component.
*
*
* The annotated method is the modified method of the Component.
*
*
* This annotation is not processed at runtime by a Service Component Runtime
* implementation. It must be processed by tools and used to add a Component
* Description to the bundle.
*
* @see "The modified attribute of the component element of a Component Description."
* @version $Id: 2a93eb9a641883494d39ddb6ecdf42779d787f7a $
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Modified {
// marker annotation
}
osgi-compendium-4.3.0/src/org/osgi/service/component/packageinfo 0000644 0001750 0001750 00000000014 11405717704 024665 0 ustar drazzib drazzib version 1.1
osgi-compendium-4.3.0/src/org/osgi/service/component/ComponentInstance.java 0000644 0001750 0001750 00000003150 11466514064 026772 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component;
/**
* A ComponentInstance encapsulates a component instance of an activated
* component configuration. ComponentInstances are created whenever a component
* configuration is activated.
*
*
* ComponentInstances are never reused. A new ComponentInstance object will be
* created when the component configuration is activated again.
*
* @ThreadSafe
* @noimplement
* @version $Id: 153a0cbf3bc5bd82afeceea35cfd6dcd8498083e $
*/
public interface ComponentInstance {
/**
* Dispose of the component configuration for this component instance. The
* component configuration will be deactivated. If the component
* configuration has already been deactivated, this method does nothing.
*/
public void dispose();
/**
* Returns the component instance of the activated component configuration.
*
* @return The component instance or {@code null} if the component
* configuration has been deactivated.
*/
public Object getInstance();
}
osgi-compendium-4.3.0/src/org/osgi/service/component/ComponentConstants.java 0000644 0001750 0001750 00000007536 11466514064 027216 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component;
/**
* Defines standard names for Service Component constants.
*
* @noimplement
* @version $Id: b2e509f16a23384cc6c90697b0fd8a70c8f9eae7 $
*/
public interface ComponentConstants {
/**
* Manifest header specifying the XML documents within a bundle that contain
* the bundle's Service Component descriptions.
*
* The attribute value may be retrieved from the {@code Dictionary}
* object returned by the {@code Bundle.getHeaders} method.
*/
public static final String SERVICE_COMPONENT = "Service-Component";
/**
* A component property for a component configuration that contains the name
* of the component as specified in the {@code name} attribute of the
* {@code component} element. The value of this property must be of
* type {@code String}.
*/
public final static String COMPONENT_NAME = "component.name";
/**
* A component property that contains the generated id for a component
* configuration. The value of this property must be of type
* {@code Long}.
*
*
* The value of this property is assigned by the Service Component Runtime
* when a component configuration is created. The Service Component Runtime
* assigns a unique value that is larger than all previously assigned values
* since the Service Component Runtime was started. These values are NOT
* persistent across restarts of the Service Component Runtime.
*/
public final static String COMPONENT_ID = "component.id";
/**
* A service registration property for a Component Factory that contains the
* value of the {@code factory} attribute. The value of this property
* must be of type {@code String}.
*/
public final static String COMPONENT_FACTORY = "component.factory";
/**
* The suffix for reference target properties. These properties contain the
* filter to select the target services for a reference. The value of this
* property must be of type {@code String}.
*/
public final static String REFERENCE_TARGET_SUFFIX = ".target";
/**
* The reason the component configuration was deactivated is unspecified.
*
* @since 1.1
*/
public static final int DEACTIVATION_REASON_UNSPECIFIED = 0;
/**
* The component configuration was deactivated because the component was disabled.
*
* @since 1.1
*/
public static final int DEACTIVATION_REASON_DISABLED = 1;
/**
* The component configuration was deactivated because a reference became unsatisfied.
*
* @since 1.1
*/
public static final int DEACTIVATION_REASON_REFERENCE = 2;
/**
* The component configuration was deactivated because its configuration was changed.
*
* @since 1.1
*/
public static final int DEACTIVATION_REASON_CONFIGURATION_MODIFIED = 3;
/**
* The component configuration was deactivated because its configuration was deleted.
*
* @since 1.1
*/
public static final int DEACTIVATION_REASON_CONFIGURATION_DELETED = 4;
/**
* The component configuration was deactivated because the component was disposed.
*
* @since 1.1
*/
public static final int DEACTIVATION_REASON_DISPOSED = 5;
/**
* The component configuration was deactivated because the bundle was stopped.
*
* @since 1.1
*/
public static final int DEACTIVATION_REASON_BUNDLE_STOPPED = 6;
}
osgi-compendium-4.3.0/src/org/osgi/service/component/ComponentFactory.java 0000644 0001750 0001750 00000003700 11466514064 026636 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.component;
import java.util.Dictionary;
/**
* When a component is declared with the {@code factory} attribute on its
* {@code component} element, the Service Component Runtime will register
* a Component Factory service to allow new component configurations to be
* created and activated rather than automatically creating and activating
* component configuration as necessary.
*
* @ThreadSafe
* @noimplement
* @version $Id: 7ec637e902c10319017d2a7c9e67bc76127dbce4 $
*/
public interface ComponentFactory {
/**
* Create and activate a new component configuration. Additional properties
* may be provided for the component configuration.
*
* @param properties Additional properties for the component configuration
* or {@code null} if there are no additional properties.
* @return A {@code ComponentInstance} object encapsulating the
* component instance of the component configuration. The component
* configuration has been activated and, if the component specifies
* a {@code service} element, the component instance has been
* registered as a service.
* @throws ComponentException If the Service Component Runtime is unable to
* activate the component configuration.
*/
public ComponentInstance newInstance(Dictionary properties);
}
osgi-compendium-4.3.0/src/org/osgi/service/application/ 0000755 0001750 0001750 00000000000 11632153414 022773 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/application/ApplicationAdminPermission.java 0000644 0001750 0001750 00000027711 11466514064 031142 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.application;
import java.security.Permission;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
/**
* This class implements permissions for manipulating applications and their
* instances.
*
* ApplicationAdminPermission can be targeted to applications that matches the
* specified filter.
*
* ApplicationAdminPermission may be granted for different actions:
* {@code lifecycle}, {@code schedule} and {@code lock}. The
* permission {@code schedule} implies the permission
* {@code lifecycle}.
*
* @version $Id: 8c7941578972d6f61ed9aeffac374a0b8c294056 $
*/
public class ApplicationAdminPermission extends Permission {
private static final long serialVersionUID = 1L;
/**
* Allows the lifecycle management of the target applications.
*/
public static final String LIFECYCLE_ACTION = "lifecycle";
/**
* Allows scheduling of the target applications. The permission to
* schedule an application implies that the scheduler can also
* manage the lifecycle of that application i.e. {@code schedule}
* implies {@code lifecycle}
*/
public static final String SCHEDULE_ACTION = "schedule";
/**
* Allows setting/unsetting the locking state of the target applications.
*/
public static final String LOCK_ACTION = "lock";
private ApplicationDescriptor applicationDescriptor;
/**
* Constructs an ApplicationAdminPermission. The {@code filter}
* specifies the target application. The {@code filter} is an
* LDAP-style filter, the recognized properties are {@code signer}
* and {@code pid}. The pattern specified in the {@code signer}
* is matched with the Distinguished Name chain used to sign the application.
* Wildcards in a DN are not matched according to the filter string rules,
* but according to the rules defined for a DN chain. The attribute
* {@code pid} is matched with the PID of the application according to
* the filter string rules.
*
* If the {@code filter} is {@code null} then it matches
* {@code "*"}. If
* {@code actions} is {@code "*"} then it identifies all the
* possible actions.
*
* @param filter
* filter to identify application. The value {@code null}
* is equivalent to {@code "*"} and it indicates "all application".
* @param actions
* comma-separated list of the desired actions granted on the
* applications or "*" means all the actions. It must not be
* {@code null}. The order of the actions in the list is
* not significant.
* @throws InvalidSyntaxException
* is thrown if the specified {@code filter} is not syntactically
* correct.
*
* @exception NullPointerException
* is thrown if the actions parameter is {@code null}
*
* @see ApplicationDescriptor
* @see org.osgi.framework.AdminPermission
*/
public ApplicationAdminPermission(String filter, String actions) throws InvalidSyntaxException {
super(filter == null ? "*" : filter);
if( filter == null )
filter = "*";
if( actions == null )
throw new NullPointerException( "Action string cannot be null!" );
this.applicationDescriptor = null;
this.filter = (filter == null ? "*" : filter);
this.actions = actions;
if( !filter.equals( "*" ) && !filter.equals( "<>" ) )
FrameworkUtil.createFilter( this.filter ); // check if the filter is valid
init();
}
/**
* This contructor should be used when creating {@code ApplicationAdminPermission}
* instance for {@code checkPermission} call.
* @param application the tareget of the operation, it must not be {@code null}
* @param actions the required operation. it must not be {@code null}
* @throws NullPointerException if any of the arguments is null.
*/
public ApplicationAdminPermission(ApplicationDescriptor application, String actions) {
super(application.getApplicationId());
if( application == null || actions == null )
throw new NullPointerException( "ApplicationDescriptor and action string cannot be null!" );
this.filter = application.getApplicationId();
this.applicationDescriptor = application;
this.actions = actions;
init();
}
/**
* This method can be used in the {@link java.security.ProtectionDomain}
* implementation in the {@code implies} method to insert the
* application ID of the current application into the permission being
* checked. This enables the evaluation of the
* {@code <<SELF>>} pseudo targets.
* @param applicationId the ID of the current application.
* @return the permission updated with the ID of the current application
*/
public ApplicationAdminPermission setCurrentApplicationId(String applicationId) {
ApplicationAdminPermission newPerm = null;
if( this.applicationDescriptor == null ) {
try {
newPerm = new ApplicationAdminPermission( this.filter, this.actions );
}catch( InvalidSyntaxException e ) {
throw new RuntimeException(e); /* this can never happen */
}
}
else
newPerm = new ApplicationAdminPermission( this.applicationDescriptor, this.actions );
newPerm.applicationID = applicationId;
return newPerm;
}
/**
* Checks if the specified {@code permission} is implied by this permission.
* The method returns true under the following conditions:
*
*
This permission was created by specifying a filter (see {@link #ApplicationAdminPermission(String, String)})
*
The implied {@code otherPermission} was created for a particular {@link ApplicationDescriptor}
* (see {@link #ApplicationAdminPermission(ApplicationDescriptor, String)})
*
The {@code filter} of this permission mathes the {@code ApplicationDescriptor} specified
* in the {@code otherPermission}. If the filter in this permission is the
* {@code <<SELF>>} pseudo target, then the currentApplicationId set in the
* {@code otherPermission} is compared to the application Id of the target
* {@code ApplicationDescriptor}.
*
The list of permitted actions in this permission contains all actions required in the
* {@code otherPermission}
*
* Otherwise the method returns false.
* @param otherPermission the implied permission
* @return true if this permission implies the {@code otherPermission}, false otherwise.
*/
public boolean implies(Permission otherPermission) {
if( otherPermission == null )
return false;
if(!(otherPermission instanceof ApplicationAdminPermission))
return false;
ApplicationAdminPermission other = (ApplicationAdminPermission) otherPermission;
if( !filter.equals("*") ) {
if( other.applicationDescriptor == null )
return false;
if( filter.equals( "<>") ) {
if( other.applicationID == null )
return false; /* it cannot be, this might be a bug */
if( !other.applicationID.equals( other.applicationDescriptor.getApplicationId() ) )
return false;
}
else {
Hashtable props = new Hashtable();
props.put( "pid", other.applicationDescriptor.getApplicationId() );
props.put( "signer", new SignerWrapper( other.applicationDescriptor ) );
Filter flt = getFilter();
if( flt == null )
return false;
if( !flt.match( props ) )
return false;
}
}
if( !actionsVector.containsAll( other.actionsVector ) )
return false;
return true;
}
public boolean equals(Object with) {
if( with == null || !(with instanceof ApplicationAdminPermission) )
return false;
ApplicationAdminPermission other = (ApplicationAdminPermission)with;
// Compare actions:
if( other.actionsVector.size() != actionsVector.size() )
return false;
for( int i=0; i != actionsVector.size(); i++ )
if( !other.actionsVector.contains( actionsVector.get( i ) ) )
return false;
return equal(this.filter, other.filter ) && equal(this.applicationDescriptor, other.applicationDescriptor)
&& equal(this.applicationID, other.applicationID);
}
/**
* Compares parameters for equality. If both object are null, they are considered
* equal.
* @param a object to compare
* @param b other object to compare
* @return true if both objects are equal or both are null
*/
private static boolean equal(Object a, Object b) {
// This equation is true if both references are null or both point
// to the same object. In both cases they are considered as equal.
if( a == b ) {
return true;
}
return a.equals(b);
}
public int hashCode() {
int hc = 0;
for( int i=0; i != actionsVector.size(); i++ )
hc ^= ((String)actionsVector.get( i )).hashCode();
hc ^= (null == this.filter )? 0 : this.filter.hashCode();
hc ^= (null == this.applicationDescriptor) ? 0 : this.applicationDescriptor.hashCode();
hc ^= (null == this.applicationID) ? 0 : this.applicationID.hashCode();
return hc;
}
/**
* Returns the actions of this permission.
* @return the actions specified when this permission was created
*/
public String getActions() {
return actions;
}
private String applicationID;
private static final Vector ACTIONS = new Vector();
private Vector actionsVector;
private final String filter;
private final String actions;
private Filter appliedFilter = null;
static {
ACTIONS.add(LIFECYCLE_ACTION);
ACTIONS.add(SCHEDULE_ACTION);
ACTIONS.add(LOCK_ACTION);
}
private static Vector actionsVector(String actions) {
Vector v = new Vector();
StringTokenizer t = new StringTokenizer(actions.toUpperCase(), ",");
while (t.hasMoreTokens()) {
String action = t.nextToken().trim();
v.add(action.toLowerCase());
}
if( v.contains( SCHEDULE_ACTION ) && !v.contains( LIFECYCLE_ACTION ) )
v.add( LIFECYCLE_ACTION );
return v;
}
private static class SignerWrapper extends Object {
private String pattern;
private ApplicationDescriptor appDesc;
/**
* @param pattern
*/
public SignerWrapper(String pattern) {
this.pattern = pattern;
}
SignerWrapper(ApplicationDescriptor appDesc) {
this.appDesc = appDesc;
}
public boolean equals(Object o) {
if (!(o instanceof SignerWrapper))
return false;
SignerWrapper other = (SignerWrapper) o;
ApplicationDescriptor matchAppDesc = (ApplicationDescriptor) (appDesc != null ? appDesc : other.appDesc);
String matchPattern = appDesc != null ? other.pattern : pattern;
return matchAppDesc.matchDNChain(matchPattern);
}
}
private void init() {
actionsVector = actionsVector( actions );
if ( actions.equals("*") )
actionsVector = actionsVector( LIFECYCLE_ACTION + "," + SCHEDULE_ACTION + "," + LOCK_ACTION );
else if (!ACTIONS.containsAll(actionsVector))
throw new IllegalArgumentException("Illegal action!");
applicationID = null;
}
private Filter getFilter() {
if (appliedFilter == null) {
try {
appliedFilter = FrameworkUtil.createFilter(filter);
} catch (InvalidSyntaxException e) {
//we will return null
}
}
return appliedFilter;
}
}
osgi-compendium-4.3.0/src/org/osgi/service/application/package-info.java 0000644 0001750 0001750 00000002536 11466514064 026177 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Application Package Version 1.1.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.service.application; version="[1.1,1.2)"}
*
* @version $Id: 49d2e45d560437599c4e283251eb4b15b0961ae5 $
*/
package org.osgi.service.application;
osgi-compendium-4.3.0/src/org/osgi/service/application/ApplicationHandle.java 0000644 0001750 0001750 00000025760 11466514064 027236 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.application;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import org.osgi.framework.Constants;
/**
* ApplicationHandle is an OSGi service interface which represents an instance
* of an application. It provides the functionality to query and manipulate the
* lifecycle state of the represented application instance. It defines constants
* for the lifecycle states.
*
* @version $Id: 10f890813548235e11bb5cd7f9f1866dcb18d381 $
*/
public abstract class ApplicationHandle {
/*
* NOTE: An implementor may also choose to replace this class in
* their distribution with a class that directly interfaces with the
* org.osgi.service.application implementation. This replacement class MUST NOT alter the
* public/protected signature of this class.
*/
/**
* The property key for the unique identifier (PID) of the application
* instance.
*/
public static final String APPLICATION_PID = Constants.SERVICE_PID;
/**
* The property key for the pid of the corresponding application descriptor.
*/
public final static String APPLICATION_DESCRIPTOR = "application.descriptor";
/**
* The property key for the state of this application instance.
*/
public final static String APPLICATION_STATE = "application.state";
/**
* The property key for the supports exit value property of this application
* instance.
*
* @since 1.1
*/
public final static String APPLICATION_SUPPORTS_EXITVALUE = "application.supports.exitvalue";
/**
* The application instance is running. This is the initial state of a newly
* created application instance.
*/
public final static String RUNNING = "RUNNING";
/**
* The application instance is being stopped. This is the state of the
* application instance during the execution of the {@code destroy()}
* method.
*/
public final static String STOPPING = "STOPPING";
private final String instanceId;
private final ApplicationDescriptor descriptor;
/**
* Application instance identifier is specified by the container when the
* instance is created. The instance identifier must remain static for the
* lifetime of the instance, it must remain the same even across framework
* restarts for the same application instance. This value must be the same
* as the {@code service.pid} service property of this application
* handle.
*
* The instance identifier should follow the following scheme:
* <application descriptor PID>.<index>
* where <application descriptor PID> is the PID of the
* corresponding {@code ApplicationDescriptor} and <index>
* is a unique integer index assigned by the application container.
* Even after destroying the application index the same index value should not
* be reused in a reasonably long timeframe.
*
* @param instanceId the instance identifier of the represented application
* instance. It must not be null.
*
* @param descriptor the {@code ApplicationDescriptor} of the represented
* application instance. It must not be null.
*
* @throws NullPointerException if any of the arguments is null.
*/
protected ApplicationHandle(String instanceId, ApplicationDescriptor descriptor ) {
if( (null == instanceId) || (null == descriptor) ) {
throw new NullPointerException("Parameters must not be null!");
}
this.instanceId = instanceId;
this.descriptor = descriptor;
try {
delegate = new Delegate();
delegate.setApplicationHandle( this, descriptor.delegate );
}
catch (Exception e) {
// Too bad ...
e.printStackTrace();
System.err
.println("No implementation available for ApplicationDescriptor, property is: "
+ Delegate.cName);
}
}
/**
* Retrieves the {@code ApplicationDescriptor} to which this
* {@code ApplicationHandle} belongs.
*
* @return The corresponding {@code ApplicationDescriptor}
*/
public final ApplicationDescriptor getApplicationDescriptor() {
return descriptor;
}
/**
* Get the state of the application instance.
*
* @return the state of the application.
*
* @throws IllegalStateException
* if the application handle is unregistered
*/
public abstract String getState();
/**
* Returns the exit value for the application instance. The timeout
* specifies how the method behaves when the application has not yet
* terminated. A negative, zero or positive value may be used.
*
*
negative - The method does not wait for termination. If the
* application has not terminated then an {@code ApplicationException}
* is thrown.
*
*
zero - The method waits until the application terminates.
*
*
positive - The method waits until the application terminates or the
* timeout expires. If the timeout expires and the application has not
* terminated then an {@code ApplicationException} is thrown.
*
*
* The default implementation throws an
* {@code UnsupportedOperationException}. The application model should
* override this method if exit values are supported.
*
*
* @param timeout The maximum time in milliseconds to wait for the
* application to timeout.
* @return The exit value for the application instance. The value is
* application specific.
* @throws UnsupportedOperationException If the application model does not
* support exit values.
* @throws InterruptedException If the thread is interrupted while waiting
* for the timeout.
* @throws ApplicationException If the application has not terminated. The
* error code will be
* {@link ApplicationException#APPLICATION_EXITVALUE_NOT_AVAILABLE}.
*
* @since 1.1
*/
public Object getExitValue(long timeout) throws ApplicationException, InterruptedException{
throw new UnsupportedOperationException();
}
/**
* Returns the unique identifier of this instance. This value is also
* available as a service property of this application handle's service.pid.
*
* @return the unique identifier of the instance
*/
public final String getInstanceId() {
return instanceId;
}
/**
* The application instance's lifecycle state can be influenced by this
* method. It lets the application instance perform operations to stop
* the application safely, e.g. saving its state to a permanent storage.
*
* The method must check if the lifecycle transition is valid; a STOPPING
* application cannot be stopped. If it is invalid then the method must
* exit. Otherwise the lifecycle state of the application instance must be
* set to STOPPING. Then the destroySpecific() method must be called to
* perform any application model specific steps for safe stopping of the
* represented application instance.
*
* At the end the {@code ApplicationHandle} must be unregistered.
* This method should free all the resources related to this
* {@code ApplicationHandle}.
*
* When this method is completed the application instance has already made
* its operations for safe stopping, the ApplicationHandle has been
* unregistered and its related resources has been freed. Further calls on
* this application should not be made because they may have unexpected
* results.
*
* @throws SecurityException
* if the caller doesn't have "lifecycle"
* {@code ApplicationAdminPermission} for the corresponding application.
*
* @throws IllegalStateException
* if the application handle is unregistered
*/
public final void destroy() {
try {
delegate.destroy();
}catch( SecurityException se ) {
descriptor.isLaunchableSpecific(); /* check whether the bundle was uninstalled */
/* if yes, throws IllegalStateException */
throw se; /* otherwise throw the caught SecurityException */
}
destroySpecific();
}
/**
* Called by the destroy() method to perform application model specific
* steps to stop and destroy an application instance safely.
*
* @throws IllegalStateException
* if the application handle is unregistered
*/
protected abstract void destroySpecific();
Delegate delegate;
/**
* This class will load the class named
* by the org.osgi.vendor.application.ApplicationHandle and delegate
* method calls to an instance of the class.
*/
static class Delegate {
static String cName;
static Class implementation;
static Method setApplicationHandle;
static Method destroy;
static {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run(){
cName = System.getProperty("org.osgi.vendor.application.ApplicationHandle");
if (cName == null) {
throw new NoClassDefFoundError("org.osgi.vendor.application.ApplicationHandle property must be set");
}
try {
implementation = Class.forName(cName);
}
catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.toString());
}
try {
setApplicationHandle = implementation.getMethod("setApplicationHandle",
new Class[] {ApplicationHandle.class, Object.class});
destroy = implementation.getMethod("destroy",
new Class[] {});
}
catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.toString());
}
return null;
}
});
}
Object target;
Delegate() throws Exception {
target = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
return implementation.newInstance();
}
});
}
void setApplicationHandle(ApplicationHandle d, ApplicationDescriptor.Delegate descriptor ) {
try {
try {
setApplicationHandle.invoke(target, new Object[] {d, descriptor.target});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
void destroy() {
try {
try {
destroy.invoke(target, new Object[] {});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
}
osgi-compendium-4.3.0/src/org/osgi/service/application/ScheduledApplication.java 0000644 0001750 0001750 00000013760 11466514064 027740 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.application;
import java.util.Map;
/**
* It is allowed to schedule an application based on a specific event.
* ScheduledApplication service keeps the schedule information. When the
* specified event is fired a new instance must be launched. Note that launching
* operation may fail because e.g. the application is locked.
*
* Each {@code ScheduledApplication} instance has an identifier which is
* unique within the scope of the application being scheduled.
*
* {@code ScheduledApplication} instances are registered as services. The
* {@link #APPLICATION_PID} service property contains the PID of the application
* being scheduled, the {@link #SCHEDULE_ID} service property contains the
* schedule identifier.
*
* @version $Id: f3385ad4cf9ce8f802ab44bd9bc76f865960b6e0 $
*/
public interface ScheduledApplication {
/**
* The property key for the identifier of the application being scheduled.
*/
public static final String APPLICATION_PID = ApplicationDescriptor.APPLICATION_PID;
/**
* The property key for the schedule identifier. The identifier is unique
* within the scope of the application being scheduled.
*/
public static final String SCHEDULE_ID = "schedule.id";
/**
* The key for the startup argument used to pass the event object that
* triggered the schedule to launch the application instance.
* The event is passed in a {@link java.security.GuardedObject}
* protected by the corresponding
* {@link org.osgi.service.event.TopicPermission}.
*/
public static final String TRIGGERING_EVENT = "org.osgi.triggeringevent";
/**
* The topic name for the virtual timer topic. Time based schedules
* should be created using this topic.
*/
public static final String TIMER_TOPIC = "org/osgi/application/timer";
/**
* The name of the year attribute of a virtual timer event. The value is
* defined by {@link java.util.Calendar#YEAR}.
*/
public static final String YEAR = "year";
/**
* The name of the month attribute of a virtual timer event. The value is
* defined by {@link java.util.Calendar#MONTH}.
*/
public static final String MONTH = "month";
/**
* The name of the day of month attribute of a virtual timer event. The value is
* defined by {@link java.util.Calendar#DAY_OF_MONTH}.
*/
public static final String DAY_OF_MONTH = "day_of_month";
/**
* The name of the day of week attribute of a virtual timer event. The value is
* defined by {@link java.util.Calendar#DAY_OF_WEEK}.
*/
public static final String DAY_OF_WEEK = "day_of_week";
/**
* The name of the hour of day attribute of a virtual timer event. The value is
* defined by {@link java.util.Calendar#HOUR_OF_DAY}.
*/
public static final String HOUR_OF_DAY = "hour_of_day";
/**
* The name of the minute attribute of a virtual timer event. The value is
* defined by {@link java.util.Calendar#MINUTE}.
*/
public static final String MINUTE = "minute";
/**
* Returns the identifier of this schedule. The identifier is unique within
* the scope of the application that the schedule is related to.
* @return the identifier of this schedule
*
*/
public String getScheduleId();
/**
* Queries the topic of the triggering event. The topic may contain a
* trailing asterisk as wildcard.
*
* @return the topic of the triggering event
*
* @throws IllegalStateException
* if the scheduled application service is unregistered
*/
public String getTopic();
/**
* Queries the event filter for the triggering event.
*
* @return the event filter for triggering event
*
* @throws IllegalStateException
* if the scheduled application service is unregistered
*/
public String getEventFilter();
/**
* Queries if the schedule is recurring.
*
* @return true if the schedule is recurring, otherwise returns false
*
* @throws IllegalStateException
* if the scheduled application service is unregistered
*/
public boolean isRecurring();
/**
* Retrieves the ApplicationDescriptor which represents the application and
* necessary for launching.
*
* @return the application descriptor that
* represents the scheduled application
*
* @throws IllegalStateException
* if the scheduled application service is unregistered
*/
public ApplicationDescriptor getApplicationDescriptor();
/**
* Queries the startup arguments specified when the application was
* scheduled. The method returns a copy of the arguments, it is not possible
* to modify the arguments after scheduling.
*
* @return the startup arguments of the scheduled application. It may be
* null if null argument was specified.
*
* @throws IllegalStateException
* if the scheduled application service is unregistered
*/
public Map getArguments();
/**
* Cancels this schedule of the application.
*
* @throws SecurityException
* if the caller doesn't have "schedule"
* ApplicationAdminPermission for the scheduled application.
* @throws IllegalStateException
* if the scheduled application service is unregistered
*/
public void remove();
}
osgi-compendium-4.3.0/src/org/osgi/service/application/ApplicationException.java 0000644 0001750 0001750 00000012241 11466514064 027767 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.application;
/**
* This exception is used to indicate problems related to application lifecycle
* management.
*
* {@code ApplicationException} object is created by the Application Admin
* to denote an exception condition in the lifecycle of an application.
* {@code ApplicationException}s should not be created by developers.
* {@code ApplicationException}s are associated with an error code. This
* code describes the type of problem reported in this exception. The possible
* codes are:
*
*
{@link #APPLICATION_LOCKED} - The application couldn't be launched
* because it is locked.
*
{@link #APPLICATION_NOT_LAUNCHABLE} - The application is not in
* launchable state.
*
{@link #APPLICATION_INTERNAL_ERROR} - An exception was thrown by the
* application or its container during launch.
*
{@link #APPLICATION_SCHEDULING_FAILED} - The scheduling of an application
* failed.
*
{@link #APPLICATION_DUPLICATE_SCHEDULE_ID} - The application scheduling
* failed because the specified identifier is already in use.
*
{@link #APPLICATION_EXITVALUE_NOT_AVAILABLE} - The exit value is not
* available for an application instance because the instance has not
* terminated.
*
{@link #APPLICATION_INVALID_STARTUP_ARGUMENT} - One of the specified
* startup arguments is invalid, for example its type is not permitted.
*
*
* @version $Id: be377d8ecd052974b3c5952c95af5c3df7334759 $
*/
public class ApplicationException extends Exception {
private static final long serialVersionUID = -7173190453622508207L;
private final int errorCode;
/**
* The application couldn't be launched because it is locked.
*/
public static final int APPLICATION_LOCKED = 0x01;
/**
* The application is not in launchable state, it's
* {@link ApplicationDescriptor#APPLICATION_LAUNCHABLE}
* attribute is false.
*/
public static final int APPLICATION_NOT_LAUNCHABLE = 0x02;
/**
* An exception was thrown by the application or the corresponding container
* during launch. The exception is available from {@code getCause()}.
*/
public static final int APPLICATION_INTERNAL_ERROR = 0x03;
/**
* The application schedule could not be created due to some internal error
* (for example, the schedule information couldn't be saved due to some
* storage error).
*/
public static final int APPLICATION_SCHEDULING_FAILED = 0x04;
/**
* The application scheduling failed because the specified identifier
* is already in use.
*/
public static final int APPLICATION_DUPLICATE_SCHEDULE_ID = 0x05;
/**
* The exit value is not available for an application instance because the
* instance has not terminated.
*
* @since 1.1
*/
public static final int APPLICATION_EXITVALUE_NOT_AVAILABLE = 0x06;
/**
* One of the specified startup arguments is invalid, for example its
* type is not permitted.
*
* @since 1.1
*/
public static final int APPLICATION_INVALID_STARTUP_ARGUMENT = 0x07;
/**
* Creates an {@code ApplicationException} with the specified error code.
* @param errorCode The code of the error
*/
public ApplicationException(int errorCode) {
super();
this.errorCode = errorCode;
}
/**
* Creates a {@code ApplicationException} that wraps another exception.
*
* @param errorCode The code of the error
* @param cause The cause of this exception.
*/
public ApplicationException(int errorCode, Throwable cause) {
super(cause);
this.errorCode = errorCode;
}
/**
* Creates an {@code ApplicationException} with the specified error code.
* @param errorCode The code of the error
* @param message The associated message
*/
public ApplicationException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
/**
* Creates a {@code ApplicationException} that wraps another exception.
*
* @param errorCode The code of the error
* @param message The associated message.
* @param cause The cause of this exception.
*/
public ApplicationException(int errorCode, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
/**
* Returns the cause of this exception or {@code null} if no cause was
* set.
*
* @return The cause of this exception or {@code null} if no cause was
* set.
*/
public Throwable getCause() {
return super.getCause();
}
/**
* Returns the error code associated with this exception.
*
* @return The error code of this exception.
*/
public int getErrorCode() {
return errorCode;
}
}
osgi-compendium-4.3.0/src/org/osgi/service/application/packageinfo 0000644 0001750 0001750 00000000014 11405717704 025166 0 ustar drazzib drazzib version 1.1
osgi-compendium-4.3.0/src/org/osgi/service/application/ApplicationDescriptor.java 0000644 0001750 0001750 00000060643 11466514064 030160 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.application;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Map;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
/**
* An OSGi service that represents an installed application and stores
* information about it. The application descriptor can be used for instance
* creation.
*
* @version $Id: 1486beb82b5cf1974523306b034acfcbfeb6d73a $
*/
public abstract class ApplicationDescriptor {
/*
* NOTE: An implementor may also choose to replace this class in
* their distribution with a class that directly interfaces with the
* org.osgi.service.application implementation. This replacement class MUST NOT alter the
* public/protected signature of this class.
*/
/**
* The property key for the localized name of the application.
*/
public static final String APPLICATION_NAME = "application.name";
/**
* The property key for the localized icon of the application.
*/
public static final String APPLICATION_ICON = "application.icon";
/**
* The property key for the unique identifier (PID) of the application.
*/
public static final String APPLICATION_PID = Constants.SERVICE_PID;
/**
* The property key for the version of the application.
*/
public static final String APPLICATION_VERSION = "application.version";
/**
* The property key for the name of the application vendor.
*/
public static final String APPLICATION_VENDOR = Constants.SERVICE_VENDOR;
/**
* The property key for the visibility property of the application.
*/
public static final String APPLICATION_VISIBLE = "application.visible";
/**
* The property key for the launchable property of the application.
*/
public static final String APPLICATION_LAUNCHABLE = "application.launchable";
/**
* The property key for the locked property of the application.
*/
public static final String APPLICATION_LOCKED = "application.locked";
/**
* The property key for the localized description of the application.
*/
public static final String APPLICATION_DESCRIPTION = "application.description";
/**
* The property key for the localized documentation of the application.
*/
public static final String APPLICATION_DOCUMENTATION = "application.documentation";
/**
* The property key for the localized copyright notice of the application.
*/
public static final String APPLICATION_COPYRIGHT = "application.copyright";
/**
* The property key for the localized license of the application.
*/
public static final String APPLICATION_LICENSE = "application.license";
/**
* The property key for the application container of the application.
*/
public static final String APPLICATION_CONTAINER = "application.container";
/**
* The property key for the location of the application.
*/
public static final String APPLICATION_LOCATION = "application.location";
private final String pid;
/**
* Constructs the {@code ApplicationDescriptor}.
*
* @param applicationId
* The identifier of the application. Its value is also available
* as the {@code service.pid} service property of this
* {@code ApplicationDescriptor} service. This parameter must not
* be {@code null}.
* @throws NullPointerException if the specified {@code applicationId} is null.
*/
protected ApplicationDescriptor(String applicationId) {
if(null == applicationId ) {
throw new NullPointerException("Application ID must not be null!");
}
this.pid = applicationId;
try {
delegate = new Delegate();
delegate.setApplicationDescriptor( this, applicationId );
}
catch (Exception e) {
// Too bad ...
e.printStackTrace();
System.err
.println("No implementation available for ApplicationDescriptor, property is: "
+ Delegate.cName);
}
}
/**
* Returns the identifier of the represented application.
*
* @return the identifier of the represented application
*/
public final String getApplicationId() {
return pid;
}
/**
* This method verifies whether the specified {@code pattern}
* matches the Distinguished Names of any of the certificate chains
* used to authenticate this application.
*
* The {@code pattern} must adhere to the
* syntax defined in {@link org.osgi.service.application.ApplicationAdminPermission}
* for signer attributes.
*
* This method is used by {@link ApplicationAdminPermission#implies(java.security.Permission)} method
* to match target {@code ApplicationDescriptor} and filter.
*
* @param pattern a pattern for a chain of Distinguished Names. It must not be null.
* @return {@code true} if the specified pattern matches at least
* one of the certificate chains used to authenticate this application
* @throws NullPointerException if the specified {@code pattern} is null.
* @throws IllegalStateException if the application descriptor was
* unregistered
*/
public abstract boolean matchDNChain( String pattern );
/**
* Returns the properties of the application descriptor as key-value pairs.
* The return value contains the locale aware and unaware properties as
* well. The returned {@code Map} will include the service
* properties of this {@code ApplicationDescriptor} as well.
*
* This method will call the {@code getPropertiesSpecific} method
* to enable the container implementation to insert application model and/or
* container implementation specific properties.
*
* The returned {@link java.util.Map} will contain the standard OSGi service
* properties as well
* (e.g. service.id, service.vendor etc.) and specialized application
* descriptors may offer further service properties. The returned Map contains
* a snapshot of the properties. It will not reflect further changes in the
* property values nor will the update of the Map change the corresponding
* service property.
*
* @param locale
* the locale string, it may be null, the value null means the
* default locale. If the provided locale is the empty String
* ({@code ""})then raw (non-localized) values are returned.
*
* @return copy of the service properties of this application descriptor service,
* according to the specified locale. If locale is null then the
* default locale's properties will be returned. (Since service
* properties are always exist it cannot return null.)
*
* @throws IllegalStateException
* if the application descriptor is unregistered
*/
public final Map getProperties(String locale) {
Map props = getPropertiesSpecific( locale );
/* currently the ApplicationDescriptor manages the load/save of locking */
boolean isLocked = delegate.isLocked(); // the real locking state
Boolean containerLocked = (Boolean)props.remove( APPLICATION_LOCKED );
if( containerLocked != null && containerLocked.booleanValue() != isLocked ) {
try {
if( isLocked ) /* if the container's information is not correct */
lockSpecific(); /* about the locking state (after loading the lock states) */
else
unlockSpecific();
}catch( Exception e ) {}
}
/* replace the container's lock with the application model's lock, that's the correct */
props.put( APPLICATION_LOCKED, new Boolean( isLocked ) );
return props;
}
/**
* Container implementations can provide application model specific
* and/or container implementation specific properties via this
* method.
*
* Localizable properties must be returned localized if the provided
* {@code locale} argument is not the empty String. The value
* {@code null} indicates to use the default locale, for other
* values the specified locale should be used.
*
* The returned {@link java.util.Map} must contain the standard OSGi service
* properties as well
* (e.g. service.id, service.vendor etc.) and specialized application
* descriptors may offer further service properties.
* The returned {@code Map}
* contains a snapshot of the properties. It will not reflect further changes in the
* property values nor will the update of the Map change the corresponding
* service property.
* @param locale the locale to be used for localizing the properties.
* If {@code null} the default locale should be used. If it is
* the empty String ({@code ""}) then raw (non-localized) values
* should be returned.
*
* @return the application model specific and/or container implementation
* specific properties of this application descriptor.
*
* @throws IllegalStateException
* if the application descriptor is unregistered
*/
protected abstract Map getPropertiesSpecific(String locale);
/**
* Launches a new instance of an application. The {@code args} parameter
* specifies the startup parameters for the instance to be launched, it may
* be null.
*
* The following steps are made:
*
*
Check for the appropriate permission.
*
Check the locking state of the application. If locked then throw an
* {@link ApplicationException} with the reason code
* {@link ApplicationException#APPLICATION_LOCKED}.
*
Calls the {@code launchSpecific()} method to create and start an
* application instance.
*
Returns the {@code ApplicationHandle} returned by the
* launchSpecific()
*
* The caller has to have ApplicationAdminPermission(applicationPID,
* "launch") in order to be able to perform this operation.
*
* The {@code Map} argument of the launch method contains startup arguments
* for the application. The keys used in the Map must be non-null, non-empty
* {@code String} objects. They can be standard or application specific.
* OSGi defines the {@code org.osgi.triggeringevent} key to be used to pass
* the triggering event to a scheduled application, however in the future it
* is possible that other well-known keys will be defined. To avoid unwanted
* clashes of keys, the following rules should be applied:
*
*
The keys starting with the dash (-) character are application
* specific, no well-known meaning should be associated with them.
*
Well-known keys should follow the reverse domain name based naming.
* In particular, the keys standardized in OSGi should start with
* {@code org.osgi.}.
*
*
* The method is synchronous, it return only when the application instance
* was successfully started or the attempt to start it failed.
*
* This method never returns {@code null}. If launching an application
* fails, the appropriate exception is thrown.
*
* @param arguments Arguments for the newly launched application, may be
* null
*
* @return the registered ApplicationHandle, which represents the newly
* launched application instance. Never returns {@code null}.
*
* @throws SecurityException if the caller doesn't have "lifecycle"
* ApplicationAdminPermission for the application.
* @throws ApplicationException if starting the application failed
* @throws IllegalStateException if the application descriptor is
* unregistered
* @throws IllegalArgumentException if the specified {@code Map} contains
* invalid keys (null objects, empty {@code String} or a key that is
* not {@code String})
*/
public final ApplicationHandle launch(Map arguments)
throws ApplicationException {
try {
delegate.launch(arguments);
}catch( SecurityException se ) {
isLaunchableSpecific(); /* check whether the bundle was uninstalled */
/* if yes, throws IllegalStateException */
throw se; /* otherwise throw the catched SecurityException */
}
if( !isLaunchableSpecific() )
throw new ApplicationException(ApplicationException.APPLICATION_NOT_LAUNCHABLE,
"Cannot launch the application!");
try {
return launchSpecific(arguments);
} catch(IllegalStateException ise) {
throw ise;
} catch(SecurityException se) {
throw se;
} catch( ApplicationException ae) {
throw ae;
} catch(Exception t) {
throw new ApplicationException(ApplicationException.APPLICATION_INTERNAL_ERROR, t);
}
}
/**
* Called by launch() to create and start a new instance in an application
* model specific way. It also creates and registeres the application handle
* to represent the newly created and started instance and registeres it.
* The method is synchronous, it return only when the application instance was
* successfully started or the attempt to start it failed.
*
* This method must not return {@code null}. If launching the application
* failed, and exception must be thrown.
*
* @param arguments
* the startup parameters of the new application instance, may be
* null
*
* @return the registered application model
* specific application handle for the newly created and started
* instance.
*
* @throws IllegalStateException
* if the application descriptor is unregistered
* @throws Exception
* if any problem occurs.
*/
protected abstract ApplicationHandle launchSpecific(Map arguments)
throws Exception;
/**
* This method is called by launch() to verify that according to the
* container, the application is launchable.
*
* @return true, if the application is launchable according to the
* container, false otherwise.
*
* @throws IllegalStateException
* if the application descriptor is unregistered
*/
protected abstract boolean isLaunchableSpecific();
/**
* Schedules the application at a specified event. Schedule information
* should not get lost even if the framework or the device restarts so it
* should be stored in a persistent storage. The method registers a
* {@link ScheduledApplication} service in Service Registry, representing
* the created schedule.
*
* The {@code Map} argument of the method contains startup arguments for the
* application. The keys used in the Map must be non-null, non-empty
* {@code String} objects. The argument values must be of primitive types,
* wrapper classes of primitive types, {@code String} or arrays or
* collections of these.
*
* The created schedules have a unique identifier within the scope of this
* {@code ApplicationDescriptor}. This identifier can be specified in the
* {@code scheduleId} argument. If this argument is {@code null}, the
* identifier is automatically generated.
*
* @param scheduleId the identifier of the created schedule. It can be
* {@code null}, in this case the identifier is automatically
* generated.
* @param arguments the startup arguments for the scheduled application, may
* be null
* @param topic specifies the topic of the triggering event, it may contain
* a trailing asterisk as wildcard, the empty string is treated as
* "*", must not be null
* @param eventFilter specifies and LDAP filter to filter on the properties
* of the triggering event, may be null
* @param recurring if the recurring parameter is false then the application
* will be launched only once, when the event firstly occurs. If the
* parameter is true then scheduling will take place for every event
* occurrence; i.e. it is a recurring schedule
*
* @return the registered scheduled application service
*
* @throws NullPointerException if the topic is {@code null}
* @throws InvalidSyntaxException if the specified {@code eventFilter} is
* not syntactically correct
* @throws ApplicationException if the schedule couldn't be created. The
* possible error codes are
*
*
* {@link ApplicationException#APPLICATION_DUPLICATE_SCHEDULE_ID} if
* the specified {@code scheduleId} is already used for this
* {@code ApplicationDescriptor}
* {@link ApplicationException#APPLICATION_SCHEDULING_FAILED} if the
* scheduling failed due to some internal reason (e.g. persistent
* storage error).
* {@link ApplicationException#APPLICATION_INVALID_STARTUP_ARGUMENT}
* if the specified startup argument doesn't satisfy the type or
* value constraints of startup arguments.
*
* @throws SecurityException if the caller doesn't have "schedule"
* ApplicationAdminPermission for the application.
* @throws IllegalStateException if the application descriptor is
* unregistered
* @throws IllegalArgumentException if the specified {@code Map} contains
* invalid keys (null objects, empty {@code String} or a key that is
* not {@code String})
*/
public final ScheduledApplication schedule(String scheduleId, Map arguments, String topic,
String eventFilter, boolean recurring) throws InvalidSyntaxException,
ApplicationException {
isLaunchableSpecific(); // checks if the ApplicationDescriptor was already unregistered
try {
return delegate.schedule(scheduleId, arguments, topic, eventFilter, recurring);
}catch( SecurityException se ) {
isLaunchableSpecific(); /* check whether the bundle was uninstalled */
/* if yes, throws IllegalStateException */
throw se; /* otherwise throw the catched SecurityException */
}
}
/**
* Sets the lock state of the application. If an application is locked then
* launching a new instance is not possible. It does not affect the already
* launched instances.
*
* @throws SecurityException
* if the caller doesn't have "lock" ApplicationAdminPermission
* for the application.
* @throws IllegalStateException
* if the application descriptor is unregistered
*/
public final void lock() {
try {
delegate.lock();
}catch( SecurityException se ) {
isLaunchableSpecific(); /* check whether the bundle was uninstalled */
/* if yes, throws IllegalStateException */
throw se; /* otherwise throw the catched SecurityException */
}
lockSpecific();
}
/**
* This method is used to notify the container implementation that the
* corresponding application has been locked and it should update the
* {@code application.locked} service property accordingly.
* @throws IllegalStateException
* if the application descriptor is unregistered
*/
protected abstract void lockSpecific();
/**
* Unsets the lock state of the application.
*
* @throws SecurityException
* if the caller doesn't have "lock" ApplicationAdminPermission
* for the application.
* @throws IllegalStateException
* if the application descriptor is unregistered
*/
public final void unlock() {
try {
delegate.unlock();
}catch( SecurityException se ) {
isLaunchableSpecific(); /* check whether the bundle was uninstalled */
/* if yes, throws IllegalStateException */
throw se; /* otherwise throw the catched SecurityException */
}
unlockSpecific();
}
/**
* This method is used to notify the container implementation that the
* corresponding application has been unlocked and it should update the
* {@code application.locked} service property accordingly.
* @throws IllegalStateException
* if the application descriptor is unregistered
*/
protected abstract void unlockSpecific();
Delegate delegate;
/**
* This class will load the class named
* by the org.osgi.vendor.application.ApplicationDescriptor and delegate
* method calls to an instance of the class.
*/
static class Delegate {
static String cName;
static Class implementation;
static Method setApplicationDescriptor;
static Method isLocked;
static Method lock;
static Method unlock;
static Method schedule;
static Method launch;
static {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
cName = System.getProperty("org.osgi.vendor.application.ApplicationDescriptor");
if (cName == null) {
throw new NoClassDefFoundError("org.osgi.vendor.application.ApplicationDescriptor property must be set");
}
try {
implementation = Class.forName(cName);
}
catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.toString());
}
try {
setApplicationDescriptor = implementation.getMethod("setApplicationDescriptor",
new Class[] {ApplicationDescriptor.class, String.class});
isLocked = implementation.getMethod("isLocked",
new Class[] {});
lock = implementation.getMethod("lock",
new Class[] {});
unlock = implementation.getMethod("unlock",
new Class[] {});
schedule = implementation.getMethod("schedule",
new Class[] {String.class, Map.class, String.class, String.class,
boolean.class});
launch = implementation.getMethod("launch",
new Class[] {Map.class});
}
catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.toString());
}
return null;
}
});
}
Object target;
Delegate() throws Exception {
target = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
return implementation.newInstance();
}
});
}
void setApplicationDescriptor(ApplicationDescriptor d, String pid ) {
try {
try {
setApplicationDescriptor.invoke(target, new Object[] {d, pid});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
boolean isLocked() {
try {
try {
return ((Boolean)isLocked.invoke(target, new Object[] {})).booleanValue();
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
void lock() {
try {
try {
lock.invoke(target, new Object[] {});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
void unlock() {
try {
try {
unlock.invoke(target, new Object[] {});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
ScheduledApplication schedule(String scheduleId, Map args, String topic, String filter,
boolean recurs) throws InvalidSyntaxException, ApplicationException {
try {
try {
return (ScheduledApplication)schedule.invoke(target, new Object[] {scheduleId, args, topic, filter,
new Boolean(recurs)});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (InvalidSyntaxException e) {
throw e;
}
catch (ApplicationException e) {
throw e;
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
void launch(Map arguments) throws ApplicationException {
try {
try {
launch.invoke(target, new Object[] {arguments});
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
catch (ApplicationException e) {
throw e;
}
catch (Error e) {
throw e;
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
}
osgi-compendium-4.3.0/src/org/osgi/service/event/ 0000755 0001750 0001750 00000000000 11632153414 021611 5 ustar drazzib drazzib osgi-compendium-4.3.0/src/org/osgi/service/event/package-info.java 0000644 0001750 0001750 00000002514 11466514064 025011 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Event Admin Package Version 1.3.
*
*
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
*
*
* Example import for consumers using the API in this package:
*
* Example import for providers implementing the API in this package:
*
* {@code Import-Package: org.osgi.service.event; version="[1.3,1.4)"}
*
* @version $Id: ce0d325e118d7610d5eea38f021525f4855b85c6 $
*/
package org.osgi.service.event;
osgi-compendium-4.3.0/src/org/osgi/service/event/TopicPermission.java 0000644 0001750 0001750 00000037011 11466514064 025614 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.event;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
/**
* A bundle's authority to publish or subscribe to event on a topic.
*
*
* A topic is a slash-separated string that defines a topic.
*
* {@code TopicPermission} has two actions: {@code publish} and
* {@code subscribe}.
*
* @ThreadSafe
* @version $Id: c5e3452781547a63cb4984d3c7e9f166b6abbd42 $
*/
public final class TopicPermission extends Permission {
static final long serialVersionUID = -5855563886961618300L;
/**
* The action string {@code publish}.
*/
public final static String PUBLISH = "publish";
/**
* The action string {@code subscribe}.
*/
public final static String SUBSCRIBE = "subscribe";
private final static int ACTION_PUBLISH = 0x00000001;
private final static int ACTION_SUBSCRIBE = 0x00000002;
private final static int ACTION_ALL = ACTION_PUBLISH
| ACTION_SUBSCRIBE;
private final static int ACTION_NONE = 0;
/**
* The actions mask.
*/
private transient int action_mask;
/**
* prefix if the name is wildcarded.
*/
private transient volatile String prefix;
/**
* The actions in canonical form.
*
* @serial
*/
private volatile String actions = null;
/**
* Defines the authority to publich and/or subscribe to a topic within the
* EventAdmin service.
*
* The name is specified as a slash-separated string. Wildcards may be used.
* For example:
*
*
* A bundle that needs to publish events on a topic must have the
* appropriate {@code TopicPermission} for that topic; similarly, a
* bundle that needs to subscribe to events on a topic must have the
* appropriate {@code TopicPermssion} for that topic.
*
*
* @param name Topic name.
* @param actions {@code publish},{@code subscribe} (canonical
* order).
*/
public TopicPermission(String name, String actions) {
this(name, parseActions(actions));
}
/**
* Package private constructor used by TopicPermissionCollection.
*
* @param name class name
* @param mask action mask
*/
TopicPermission(String name, int mask) {
super(name);
setTransients(mask);
}
/**
* Called by constructors and when deserialized.
*
* @param name topic name
* @param mask action mask
*/
private synchronized void setTransients(final int mask) {
final String name = getName();
if ((name == null) || name.length() == 0) {
throw new IllegalArgumentException("invalid name");
}
if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
throw new IllegalArgumentException("invalid action string");
}
action_mask = mask;
if (name.equals("*")) {
prefix = "";
}
else {
if (name.endsWith("/*")) {
prefix = name.substring(0, name.length() - 1);
}
else {
prefix = null;
}
}
}
/**
* Returns the current action mask.
*
* Used by the TopicPermissionCollection class.
*
* @return Current action mask.
*/
synchronized int getActionsMask() {
return action_mask;
}
/**
* Parse action string into action mask.
*
* @param actions Action string.
* @return action mask.
*/
private static int parseActions(final String actions) {
boolean seencomma = false;
int mask = ACTION_NONE;
if (actions == null) {
return mask;
}
char[] a = actions.toCharArray();
int i = a.length - 1;
if (i < 0)
return mask;
while (i != -1) {
char c;
// skip whitespace
while ((i != -1)
&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
|| c == '\f' || c == '\t'))
i--;
// check for the known strings
int matchlen;
if (i >= 8 && (a[i - 8] == 's' || a[i - 8] == 'S')
&& (a[i - 7] == 'u' || a[i - 7] == 'U')
&& (a[i - 6] == 'b' || a[i - 6] == 'B')
&& (a[i - 5] == 's' || a[i - 5] == 'S')
&& (a[i - 4] == 'c' || a[i - 4] == 'C')
&& (a[i - 3] == 'r' || a[i - 3] == 'R')
&& (a[i - 2] == 'i' || a[i - 2] == 'I')
&& (a[i - 1] == 'b' || a[i - 1] == 'B')
&& (a[i] == 'e' || a[i] == 'E')) {
matchlen = 9;
mask |= ACTION_SUBSCRIBE;
}
else
if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
&& (a[i - 5] == 'u' || a[i - 5] == 'U')
&& (a[i - 4] == 'b' || a[i - 4] == 'B')
&& (a[i - 3] == 'l' || a[i - 3] == 'L')
&& (a[i - 2] == 'i' || a[i - 2] == 'I')
&& (a[i - 1] == 's' || a[i - 1] == 'S')
&& (a[i] == 'h' || a[i] == 'H')) {
matchlen = 7;
mask |= ACTION_PUBLISH;
}
else {
// parse error
throw new IllegalArgumentException("invalid permission: "
+ actions);
}
// make sure we didn't just match the tail of a word
// like "ackbarfpublish". Also, skip to the comma.
seencomma = false;
while (i >= matchlen && !seencomma) {
switch (a[i - matchlen]) {
case ',' :
seencomma = true;
/* FALLTHROUGH */
case ' ' :
case '\r' :
case '\n' :
case '\f' :
case '\t' :
break;
default :
throw new IllegalArgumentException(
"invalid permission: " + actions);
}
i--;
}
// point i at the location of the comma minus one (or -1).
i -= matchlen;
}
if (seencomma) {
throw new IllegalArgumentException("invalid permission: " + actions);
}
return mask;
}
/**
* Determines if the specified permission is implied by this object.
*
*
* This method checks that the topic name of the target is implied by the
* topic name of this object. The list of {@code TopicPermission}
* actions must either match or allow for the list of the target object to
* imply the target {@code TopicPermission} action.
*
*
* x/y/*,"publish" -> x/y/z,"publish" is true
* *,"subscribe" -> x/y,"subscribe" is true
* *,"publish" -> x/y,"subscribe" is false
* x/y,"publish" -> x/y/z,"publish" is false
*
*
* @param p The target permission to interrogate.
* @return {@code true} if the specified {@code TopicPermission}
* action is implied by this object; {@code false} otherwise.
*/
public boolean implies(Permission p) {
if (p instanceof TopicPermission) {
TopicPermission requested = (TopicPermission) p;
int requestedMask = requested.getActionsMask();
if ((getActionsMask() & requestedMask) == requestedMask) {
String requestedName = requested.getName();
String pre = prefix;
if (pre != null) {
return requestedName.startsWith(pre);
}
return requestedName.equals(getName());
}
}
return false;
}
/**
* Returns the canonical string representation of the
* {@code TopicPermission} actions.
*
*
* Always returns present {@code TopicPermission} actions in the
* following order: {@code publish},{@code subscribe}.
*
* @return Canonical string representation of the
* {@code TopicPermission} actions.
*/
public String getActions() {
String result = actions;
if (result == null) {
StringBuffer sb = new StringBuffer();
boolean comma = false;
int mask = getActionsMask();
if ((mask & ACTION_PUBLISH) == ACTION_PUBLISH) {
sb.append(PUBLISH);
comma = true;
}
if ((mask & ACTION_SUBSCRIBE) == ACTION_SUBSCRIBE) {
if (comma)
sb.append(',');
sb.append(SUBSCRIBE);
}
actions = result = sb.toString();
}
return result;
}
/**
* Returns a new {@code PermissionCollection} object suitable for
* storing {@code TopicPermission} objects.
*
* @return A new {@code PermissionCollection} object.
*/
public PermissionCollection newPermissionCollection() {
return new TopicPermissionCollection();
}
/**
* Determines the equality of two {@code TopicPermission} objects.
*
* This method checks that specified {@code TopicPermission} has the
* same topic name and actions as this {@code TopicPermission} object.
*
* @param obj The object to test for equality with this
* {@code TopicPermission} object.
* @return {@code true} if {@code obj} is a
* {@code TopicPermission}, and has the same topic name and
* actions as this {@code TopicPermission} object;
* {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof TopicPermission)) {
return false;
}
TopicPermission tp = (TopicPermission) obj;
return (getActionsMask() == tp.getActionsMask())
&& getName().equals(tp.getName());
}
/**
* Returns the hash code value for this object.
*
* @return A hash code value for this object.
*/
public int hashCode() {
int h = 31 * 17 + getName().hashCode();
h = 31 * h + getActions().hashCode();
return h;
}
/**
* WriteObject is called to save the state of this permission object to a
* stream. The actions are serialized, and the superclass takes care of the
* name.
*/
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws IOException {
// Write out the actions. The superclass takes care of the name
// call getActions to make sure actions field is initialized
if (actions == null)
getActions();
s.defaultWriteObject();
}
/**
* readObject is called to restore the state of this permission from a
* stream.
*/
private synchronized void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
// Read in the action, then initialize the rest
s.defaultReadObject();
setTransients(parseActions(actions));
}
}
/**
* Stores a set of {@code TopicPermission} permissions.
*
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
*/
final class TopicPermissionCollection extends PermissionCollection {
static final long serialVersionUID = -614647783533924048L;
/**
* Table of permissions.
*
* @GuardedBy this
*/
private transient Map permissions;
/**
* Boolean saying if "*" is in the collection.
*
* @serial
* @GuardedBy this
*/
private boolean all_allowed;
/**
* Create an empty TopicPermissions object.
*
*/
public TopicPermissionCollection() {
permissions = new HashMap();
all_allowed = false;
}
/**
* Adds a permission to the {@code TopicPermission} objects. The key
* for the hash is the name.
*
* @param permission The {@code TopicPermission} object to add.
*
* @throws IllegalArgumentException If the permission is not a
* {@code TopicPermission} instance.
*
* @throws SecurityException If this {@code TopicPermissionCollection}
* object has been marked read-only.
*/
public void add(final Permission permission) {
if (!(permission instanceof TopicPermission)) {
throw new IllegalArgumentException("invalid permission: "
+ permission);
}
if (isReadOnly()) {
throw new SecurityException("attempt to add a Permission to a "
+ "readonly PermissionCollection");
}
final TopicPermission tp = (TopicPermission) permission;
final String name = tp.getName();
final int newMask = tp.getActionsMask();
synchronized (this) {
final TopicPermission existing = permissions
.get(name);
if (existing != null) {
final int oldMask = existing.getActionsMask();
if (oldMask != newMask) {
permissions.put(name, new TopicPermission(name, oldMask
| newMask));
}
}
else {
permissions.put(name, tp);
}
if (!all_allowed) {
if (name.equals("*"))
all_allowed = true;
}
}
}
/**
* Determines if the specified permissions implies the permissions expressed
* in {@code permission}.
*
* @param permission The Permission object to compare with this
* {@code TopicPermission} object.
*
* @return {@code true} if {@code permission} is a proper subset
* of a permission in the set; {@code false} otherwise.
*/
public boolean implies(final Permission permission) {
if (!(permission instanceof TopicPermission)) {
return false;
}
final TopicPermission requested = (TopicPermission) permission;
String name = requested.getName();
final int desired = requested.getActionsMask();
int effective = 0;
TopicPermission x;
// short circuit if the "*" Permission was added
synchronized (this) {
if (all_allowed) {
x = permissions.get("*");
if (x != null) {
effective |= x.getActionsMask();
if ((effective & desired) == desired) {
return true;
}
}
}
x = permissions.get(name);
}
// strategy:
// Check for full match first. Then work our way up the
// name looking for matches on a/b/*
if (x != null) {
// we have a direct hit!
effective |= x.getActionsMask();
if ((effective & desired) == desired) {
return true;
}
}
// work our way up the tree...
int last;
int offset = name.length() - 1;
while ((last = name.lastIndexOf("/", offset)) != -1) {
name = name.substring(0, last + 1) + "*";
synchronized (this) {
x = permissions.get(name);
}
if (x != null) {
effective |= x.getActionsMask();
if ((effective & desired) == desired) {
return true;
}
}
offset = last - 1;
}
// we don't have to check for "*" as it was already checked
// at the top (all_allowed), so we just return false
return false;
}
/**
* Returns an enumeration of all {@code TopicPermission} objects in the
* container.
*
* @return Enumeration of all {@code TopicPermission} objects.
*/
public synchronized Enumeration elements() {
List all = new ArrayList(permissions.values());
return Collections.enumeration(all);
}
/* serialization logic */
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("permissions", Hashtable.class),
new ObjectStreamField("all_allowed", Boolean.TYPE) };
private synchronized void writeObject(ObjectOutputStream out)
throws IOException {
Hashtable hashtable = new Hashtable(
permissions);
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", hashtable);
pfields.put("all_allowed", all_allowed);
out.writeFields();
}
private synchronized void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gfields = in.readFields();
Hashtable hashtable = (Hashtable) gfields
.get("permissions", null);
permissions = new HashMap(hashtable);
all_allowed = gfields.get("all_allowed", false);
}
}
osgi-compendium-4.3.0/src/org/osgi/service/event/EventHandler.java 0000644 0001750 0001750 00000004560 11466514064 025047 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.event;
/**
* Listener for Events.
*
*
* {@code EventHandler} objects are registered with the Framework service
* registry and are notified with an {@code Event} object when an event
* is sent or posted.
*
* {@code EventHandler} objects can inspect the received
* {@code Event} object to determine its topic and properties.
*
*
* {@code EventHandler} objects must be registered with a service
* property {@link EventConstants#EVENT_TOPIC} whose value is the list of topics
* in which the event handler is interested.
*
*
* Event Handler services can also be registered with an
* {@link EventConstants#EVENT_FILTER} service property to further filter the
* events. If the syntax of this filter is invalid, then the Event Handler must
* be ignored by the Event Admin service. The Event Admin service should log a
* warning.
*
* Security Considerations. Bundles wishing to monitor {@code Event}
* objects will require {@code ServicePermission[EventHandler,REGISTER]}
* to register an {@code EventHandler} service. The bundle must also have
* {@code TopicPermission[topic,SUBSCRIBE]} for the topic specified in
* the event in order to receive the event.
*
* @see Event
*
* @ThreadSafe
* @version $Id: 2b8202d10e77b774897c74714115059f46abc7e1 $
*/
public interface EventHandler {
/**
* Called by the {@link EventAdmin} service to notify the listener of an
* event.
*
* @param event The event that occurred.
*/
void handleEvent(Event event);
}
osgi-compendium-4.3.0/src/org/osgi/service/event/EventConstants.java 0000644 0001750 0001750 00000020032 11466514064 025436 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.event;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
/**
* Defines standard names for {@code EventHandler} properties.
*
* @noimplement
* @version $Id: 4416a32be106f158ab6f776219a2203ed54c9b7d $
*/
public interface EventConstants {
/**
* Service registration property specifying the {@code Event} topics of
* interest to an Event Handler service.
*
* Event handlers SHOULD be registered with this property. Each value of
* this property is a string that describe the topics in which the handler
* is interested. An asterisk ('*') may be used as a trailing wildcard.
* Event Handlers which do not have a value for this property must not
* receive events. More precisely, the value of each string must conform to
* the following grammar:
*
*
* The value of this property must be of type {@code String},
* {@code String[]}, or {@code Collection<String>}.
*
* @see Event
*/
public static final String EVENT_TOPIC = "event.topics";
/**
* Service Registration property specifying a filter to further select
* {@code Event} s of interest to an Event Handler service.
*
* Event handlers MAY be registered with this property. The value of this
* property is a string containing an LDAP-style filter specification. Any
* of the event's properties may be used in the filter expression. Each
* event handler is notified for any event which belongs to the topics in
* which the handler has expressed an interest. If the event handler is also
* registered with this service property, then the properties of the event
* must also match the filter for the event to be delivered to the event
* handler.
*
* If the filter syntax is invalid, then the Event Handler must be ignored
* and a warning should be logged.
*
*
* The value of this property must be of type {@code String}.
*
* @see Event
* @see Filter
*/
public static final String EVENT_FILTER = "event.filter";
/**
* Service Registration property specifying the delivery qualities requested
* by an Event Handler service.
*
* Event handlers MAY be registered with this property. Each value of this
* property is a string specifying a delivery quality for the Event handler.
*
*
* The value of this property must be of type {@code String},
* {@code String[]}, or {@code Collection<String>}.
*
* @see #DELIVERY_ASYNC_ORDERED
* @see #DELIVERY_ASYNC_UNORDERED
* @since 1.3
*/
public static final String EVENT_DELIVERY = "event.delivery";
/**
* Event Handler delivery quality value specifying the Event Handler
* requires asynchronously delivered events be delivered in order. Ordered
* delivery is the default for asynchronously delivered events.
*
*
* This delivery quality value is mutually exclusive with
* {@link #DELIVERY_ASYNC_UNORDERED}. However, if both this value and
* {@link #DELIVERY_ASYNC_UNORDERED} are specified for an event handler,
* this value takes precedence.
*
* @see #EVENT_DELIVERY
* @since 1.3
*/
public static final String DELIVERY_ASYNC_ORDERED = "async.ordered";
/**
* Event Handler delivery quality value specifying the Event Handler does
* not require asynchronously delivered events be delivered in order. This
* may allow an Event Admin implementation to optimize asynchronous event
* delivery by relaxing ordering requirements.
*
*
* This delivery quality value is mutually exclusive with
* {@link #DELIVERY_ASYNC_ORDERED}. However, if both this value and
* {@link #DELIVERY_ASYNC_ORDERED} are specified for an event handler,
* {@link #DELIVERY_ASYNC_ORDERED} takes precedence.
*
* @see #EVENT_DELIVERY
* @since 1.3
*/
public static final String DELIVERY_ASYNC_UNORDERED = "async.unordered";
/**
* The Distinguished Names of the signers of the bundle relevant to the
* event. The type of the value for this event property is
* {@code String} or {@code Collection} of {@code String}.
*/
public static final String BUNDLE_SIGNER = "bundle.signer";
/**
* The Bundle Symbolic Name of the bundle relevant to the event. The type of
* the value for this event property is {@code String}.
*/
public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName";
/**
* The Bundle id of the bundle relevant to the event. The type of the value
* for this event property is {@code Long}.
*
* @since 1.1
*/
public static final String BUNDLE_ID = "bundle.id";
/**
* The Bundle object of the bundle relevant to the event. The type of the
* value for this event property is {@link Bundle}.
*
* @since 1.1
*/
public static final String BUNDLE = "bundle";
/**
* The version of the bundle relevant to the event. The type of the value
* for this event property is {@link Version}.
*
* @since 1.2
*/
public static final String BUNDLE_VERSION = "bundle.version";
/**
* The forwarded event object. Used when rebroadcasting an event that was
* sent via some other event mechanism. The type of the value for this event
* property is {@code Object}.
*/
public static final String EVENT = "event";
/**
* An exception or error. The type of the value for this event property is
* {@code Throwable}.
*/
public static final String EXCEPTION = "exception";
/**
* The name of the exception type. Must be equal to the name of the class of
* the exception in the event property {@link #EXCEPTION}. The type of the
* value for this event property is {@code String}.
*
* @since 1.1
*/
public static final String EXCEPTION_CLASS = "exception.class";
/**
* The exception message. Must be equal to the result of calling
* {@code getMessage()} on the exception in the event property
* {@link #EXCEPTION}. The type of the value for this event property is
* {@code String}.
*/
public static final String EXCEPTION_MESSAGE = "exception.message";
/**
* A human-readable message that is usually not localized. The type of the
* value for this event property is {@code String}.
*/
public static final String MESSAGE = "message";
/**
* A service reference. The type of the value for this event property is
* {@link ServiceReference}.
*/
public static final String SERVICE = "service";
/**
* A service's id. The type of the value for this event property is
* {@code Long}.
*/
public static final String SERVICE_ID = Constants.SERVICE_ID;
/**
* A service's objectClass. The type of the value for this event property is
* {@code String[]}.
*/
public static final String SERVICE_OBJECTCLASS = "service.objectClass";
/**
* A service's persistent identity. The type of the value for this event
* property is {@code String}.
*/
public static final String SERVICE_PID = Constants.SERVICE_PID;
/**
* The time when the event occurred, as reported by
* {@code System.currentTimeMillis()}. The type of the value for this
* event property is {@code Long}.
*/
public static final String TIMESTAMP = "timestamp";
/**
* This constant was released with an incorrectly spelled name. It has been
* replaced by {@link #EXCEPTION_CLASS}
*
* @deprecated As of 1.1, replaced by EXCEPTION_CLASS
*/
public static final String EXECPTION_CLASS = "exception.class";
}
osgi-compendium-4.3.0/src/org/osgi/service/event/EventAdmin.java 0000644 0001750 0001750 00000003610 11466514064 024515 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.event;
/**
* The Event Admin service. Bundles wishing to publish events must obtain the
* Event Admin service and call one of the event delivery methods.
*
* @ThreadSafe
* @noimplement
* @version $Id: d21a164e318da4b9ca165d1e481e270610cc0c77 $
*/
public interface EventAdmin {
/**
* Initiate asynchronous, ordered delivery of an event. This method returns
* to the caller before delivery of the event is completed. Events are
* delivered in the order that they are received by this method.
*
* @param event The event to send to all listeners which subscribe to the
* topic of the event.
*
* @throws SecurityException If the caller does not have
* {@code TopicPermission[topic,PUBLISH]} for the topic
* specified in the event.
*/
void postEvent(Event event);
/**
* Initiate synchronous delivery of an event. This method does not return to
* the caller until delivery of the event is completed.
*
* @param event The event to send to all listeners which subscribe to the
* topic of the event.
*
* @throws SecurityException If the caller does not have
* {@code TopicPermission[topic,PUBLISH]} for the topic
* specified in the event.
*/
void sendEvent(Event event);
}
osgi-compendium-4.3.0/src/org/osgi/service/event/EventProperties.java 0000644 0001750 0001750 00000016146 11466514064 025631 0 ustar drazzib drazzib /*
* Copyright (c) OSGi Alliance (2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.osgi.service.event;
import static org.osgi.service.event.EventConstants.EVENT_TOPIC;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* The properties for an {@link Event}. An event source can create an
* EventProperties object if it needs to reuse the same event properties for
* multiple events.
*
*
* The keys are all of type {@code String}. The values are of type
* {@code Object}. The key "event.topics" is ignored as event
* topics can only be set when an {@link Event} is constructed.
*
*
* Once constructed, an EventProperties object is unmodifiable. However, the
* values of the map used to construct an EventProperties object are still
* subject to modification as they are not deeply copied.
*
* @Immutable
* @since 1.3
* @version $Id: 2b1e756cdb49df53926aede978132c26f31515ed $
*/
public class EventProperties implements Map {
/**
* The properties for an event. Keys are strings and values are objects. The
* object is unmodifiable.
*/
private final Map properties;
/**
* Create an EventProperties from the specified properties.
*
*
* The specified properties will be copied into this EventProperties.
* Properties whose key is not of type {@code String} will be ignored.
* A property with the key "event.topics" will be ignored.
*
* @param properties The properties to use for this EventProperties object
* (may be {@code null}).
*/
public EventProperties(Map properties) {
int size = (properties == null) ? 0 : properties.size();
Map p = new HashMap(size);
if (size > 0) {
for (Object key : (Set< ? >) properties.keySet()) {
if ((key instanceof String) && !EVENT_TOPIC.equals(key)) {
Object value = properties.get(key);
p.put((String) key, value);
}
}
}
// safely publish the map
this.properties = Collections.unmodifiableMap(p);
}
/**
* Create an EventProperties from the specified dictionary.
*
*
* The specified properties will be copied into this EventProperties.
* Properties whose key is not of type {@code String} will be ignored.
* A property with the key "event.topics" will be ignored.
*
* @param properties The properties to use for this EventProperties object
* (may be {@code null}).
*/
EventProperties(Dictionary properties) {
int size = (properties == null) ? 0 : properties.size();
Map p = new HashMap(size);
if (size > 0) {
for (Enumeration< ? > e = properties.keys(); e.hasMoreElements();) {
Object key = e.nextElement();
if ((key instanceof String) && !EVENT_TOPIC.equals(key)) {
Object value = properties.get(key);
p.put((String) key, value);
}
}
}
// safely publish the map
this.properties = Collections.unmodifiableMap(p);
}
/**
* This method throws {@link UnsupportedOperationException}.
*
* @throws UnsupportedOperationException if called.
*/
public void clear() {
properties.clear();
}
/**
* Indicates if the specified property is present.
*
* @param name The property name.
* @return {@code true} If the property is present, {@code false}
* otherwise.
*/
public boolean containsKey(Object name) {
return properties.containsKey(name);
}
/**
* Indicates if the specified value is present.
*
* @param value The property value.
* @return {@code true} If the value is present, {@code false}
* otherwise.
*/
public boolean containsValue(Object value) {
return properties.containsValue(value);
}
/**
* Return the property entries.
*
* @return A set containing the property name/value pairs.
*/
public Set> entrySet() {
return properties.entrySet();
}
/**
* Return the value of the specified property.
*
* @param name The name of the specified property.
* @return The value of the specified property.
*/
public Object get(Object name) {
return properties.get(name);
}
/**
* Indicate if this properties is empty.
*
* @return {@code true} If this properties is empty, {@code false}
* otherwise.
*/
public boolean isEmpty() {
return properties.isEmpty();
}
/**
* Return the names of the properties.
*
* @return The names of the properties.
*/
public Set keySet() {
return properties.keySet();
}
/**
* This method throws {@link UnsupportedOperationException}.
*
* @throws UnsupportedOperationException if called.
*/
public Object put(String key, Object value) {
return properties.put(key, value);
}
/**
* This method throws {@link UnsupportedOperationException}.
*
* @throws UnsupportedOperationException if called.
*/
public void putAll(Map< ? extends String, ? extends Object> map) {
properties.putAll(map);
}
/**
* This method throws {@link UnsupportedOperationException}.
*
* @throws UnsupportedOperationException if called.
*/
public Object remove(Object key) {
return properties.remove(key);
}
/**
* Return the number of properties.
*
* @return The number of properties.
*/
public int size() {
return properties.size();
}
/**
* Return the properties values.
*
* @return The values of the properties.
*/
public Collection