Return-Path: X-Original-To: apmail-jackrabbit-oak-dev-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-oak-dev-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 87F7F9A6C for ; Tue, 17 Apr 2012 21:29:14 +0000 (UTC) Received: (qmail 46982 invoked by uid 500); 17 Apr 2012 21:29:14 -0000 Delivered-To: apmail-jackrabbit-oak-dev-archive@jackrabbit.apache.org Received: (qmail 46959 invoked by uid 500); 17 Apr 2012 21:29:14 -0000 Mailing-List: contact oak-dev-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: oak-dev@jackrabbit.apache.org Delivered-To: mailing list oak-dev@jackrabbit.apache.org Received: (qmail 46944 invoked by uid 99); 17 Apr 2012 21:29:14 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Apr 2012 21:29:14 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=5.0 tests=RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of jukka.zitting@gmail.com designates 74.125.82.50 as permitted sender) Received: from [74.125.82.50] (HELO mail-wg0-f50.google.com) (74.125.82.50) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Apr 2012 21:29:07 +0000 Received: by wgbds12 with SMTP id ds12so6616805wgb.19 for ; Tue, 17 Apr 2012 14:28:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to:content-type; bh=Y0NRG2ZW42LU/im4HPsNb4xXedy0f1uhrFFDGUCYmCU=; b=Fhpthgi4Y9/RxXlEdF6T9uS2CU/LzJpxRUo8kD2ZIodebeQfSy6g7Yb6Zc19VwKOF9 OiM3s8fM9w0MTd5kNvgqDICOfT9f8juE7v5J/7es+11+uieGwqOcc4qgPWUVmuzWOF3D Kfzs4k1sZqab0Dp8a4TmgdDdxZGVUbj7jtJbjI28LpsCtAWXp4pcW7R466ETLM+//Dkj NcffCbnkJHLlE35r1KHxj3tHB7/1EQAazFnVy0cFfwQvgmNR3dHp3KIay944s9Ej2aAP XN5VTIR9dI6Shg6qa6Z9NytLDQoH9kFOhhO5/eAykR5gngUuTiYRnEJ0Iof32vB4jumQ Wsxg== Received: by 10.216.136.72 with SMTP id v50mr10237278wei.73.1334698126514; Tue, 17 Apr 2012 14:28:46 -0700 (PDT) MIME-Version: 1.0 Received: by 10.180.146.133 with HTTP; Tue, 17 Apr 2012 14:28:26 -0700 (PDT) From: Jukka Zitting Date: Tue, 17 Apr 2012 23:28:26 +0200 Message-ID: Subject: Oak API - a top down look To: Oak devs Content-Type: text/plain; charset=ISO-8859-1 Hi, Over the past week or two we've been going in a lot of different directions with the Oak API. Rather than comment on individual details in the various related threads and issues, let me step back a bit and outline one possible vision of how the API could/should work. Most of the included bits we already have in various places, and I'm just trying to put them together in a slightly more coherent way. So see below (HTML version at [1]) for a top-down draft of how the concepts of the API could fit together. I'm basically taking the existing RepositoryService, Connection and NodeStateEditor/TransientNodeState interfaces and casting them slightly differently with a new set of names. This is just a draft proposal, so please critique or propose alternatives, ideally in a format like this so that we'll be able to use the resulting consensus as the beginning of more comprehensive API documentation. [1] https://github.com/jukka/jackrabbit-oak/blob/trunk/oak-core/README.md BR, Jukka Zitting Oak API ------- The API for accessing core Oak functionality is located in the `org.apache.jackrabbit.oak.api` package and consists of the following key interfaces: * ContentRepository * ContentSession * ContentTree The `ContentRepository` interface represents an entire Oak content repository. The repository may local or remote, or a cluster of any size. These deployment details are all hidden behind this interface. Starting and stopping `ContentRepository` instances is the responsibility of each particular deployment and not covered by these interfaces. Repository clients should use a deployment-specific mechanism (JNDI, OSGi service, etc.) to acquire references to `ContentRepository` instances. All content in the repository is accessed through authenticated sessions acquired through the `ContentRepository.login()` method. The method takes explicit access credentials and other login details and, assuming the credentials are valid, returns a `ContentSession` instance that encapsulates this information. Session instances are `Closeable` and need to be closed to release associated resources once no longer used. The recommended access pattern is: ContentRepository repository = ...; ContentSession session = repository.login(...); try { ...; // Use the session } finally { session.close(); } All `ContentRepository` and `ContentSession` instances are thread-safe. The authenticated `ContentSession` gives you properly authorized access to the hierarchical content tree inside the repository through instances of the `ContentTree` interface. The `getCurrentContentTree()` method returns a snapshot of the current state of the content tree: ContentSession session = ...; ContentTree tree = session.getCurrentContentTree(); The returned `ContentTree` instance belongs to the client and its state is only modified in response to method calls made by the client. `ContentTree` instances are *not* thread-safe, so the client needs to ensure that they are not accessed concurrently from multiple threads. Content trees are recursive data structures that consist of named properties and subtrees that share the same namespace, but are accessed through separate methods like outlined below: ContentTree tree = ...; for (PropertyState property : tree.getProperties()) { ...; } for (ContentTree subtree : tree.getSubtrees()) { ...; } The repository content snapshot exposed by a `ContentTree` instance may become invalid over time due to garbage collection of old content, at which point an outdated snapshot will start throwing `IllegalStateExceptions` to indicate that the snapshot is no longer available. To access more recent content, a client should either call `getCurrentContentTree()` to acquire a fresh now content snapshot or use the `refresh()` method to update a given `ContentTree` to the latest state of the content repository: ContentTree tree = ...; tree.refresh(); In addition to reading repository content, the client can also make modifications to the content tree. Such content changes remain local to the particular `ContentTree` instance (and related subtrees) until explicitly committed. For example, the following code creates and commits a new subtree containing nothing but a simple property: ContentTree tree = ...; ContentTree subtree = tree.addSubtree("hello"); subtree.setProperty("message", "Hello, World!"); tree.commit(); Even other `ContentTree` instances acquired from the same `ContentSession` won't see such changes until they've been committed and the other trees refreshed. This allows a client to track multiple parallel sets of changes with just a single authenticated session.