[JSR_333-76] SQL2 DELETE/UPDATE statements Created: 23/Jul/14  Updated: 08/Sep/14  Resolved: 08/Sep/14

Status: Closed
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: lsmith77 Assignee: uncled
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: QOM, SQL2

 Description   

Just opening this so that it is at least recorded outside of the PHPCR world. For a CLI tool we extended the SQL2 syntax to also include DELETE/UPDATE. note we have not made it part of the PHPCR spec but it might be worthwhile to think about adding something like this to allow simply adhoc data changes. Of course JSR-333 is too far along to add it now.

https://github.com/phpcr/phpcr-shell/compare/1.0.0-alpha3...1.0.0-alpha4#diff-11



 Comments   
Comment by Peeter Piegaze [ 08/Sep/14 ]

We will be releasing JSR-333 as-is (after much delay)





[JSR_333-75] Allow extra keys in map returned by Event.getInfo() Created: 09/Jul/14  Updated: 08/Sep/14  Resolved: 08/Sep/14

Status: Closed
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: mduerig Assignee: uncled
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

12.3.2 Event Information explicitly requires the map returned by Event.getInfo() to be empty for all but the NODE_MOVED events. For certain uses cases it would be favourable if implementations are free to attach additional information to that map. See e.g. JCR-3765.

Instead of requiring that map to be empty (or contain exactly a certain set of keys) the specification could reserve a certain set of keys for its own use and allow applications to add other keys to the map as required.



 Comments   
Comment by Peeter Piegaze [ 08/Sep/14 ]

We will be releasing JSR-333 as-is (after much delay).





[JSR_333-74] Potential deadlock in ObservationManager.removeEventListener() Created: 16/Dec/13  Updated: 08/Sep/14  Resolved: 08/Sep/14

Status: Closed
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: None

Type: Bug Priority: Major
Reporter: jukka.zitting Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

As discussed in https://issues.apache.org/jira/browse/OAK-1290, the ObservationManager.removeEventListener() method can lead to a deadlock because it "will block until the listener has completed executing." The deadlock occurs if the thread that calls this method holds a lock that the event listener is trying to acquire. The relevant javadoc paragraph is:

A listener may be deregistered while it is being executed. The deregistration method will block until the listener has completed executing. An exception to this rule is a listener which deregisters itself from within the onEvent method. In this case, the deregistration method returns immediately, but deregistration will effectively be delayed until the listener completes.

I see two ways to avoid this deadlock scenario:

  1. Keep the behavior as-is, but add documentation that informs clients about this problem: "... To avoid potential deadlocks, the caller of this method should not hold any locks that the event listener might try to acquire."
  2. Change the contract so that the method should not block indefinitely: "A listener may be deregistered while it is being executed. No more events will be delivered to the listener once this method has returned. An implementation should not block until the listener has completed executing. An exception to this rule is a listener which deregisters itself from within the onEvent method. In this case, the deregistration method returns immediately, but deregistration will effectively be delayed until the listener completes. To avoid potential deadlocks with implementations that might block, the caller of this method should not hold any locks that the event listener might try to acquire."

The first is fully backwards compatible, the second safer. I'm not sure if there are any clients out there that rely on the specified blocking behavior.



 Comments   
Comment by rhauch [ 16/Dec/13 ]

I agree that blocking doesn't really make much sense, especially because the phrase "until the listener has completed executing" is not clearly defined. What does it mean for a listener that is continually receiving additional lists of events (via the event iterator) to "complete executing".

But the proposed solutions still seem overly complicated.

Isn't the intention to simply require that a listener's "onEvent(EventIterator)" method should be atomic – once called with an iterator, the set of events as seen by the listener shouldn't be changed by deregistration. This includes the case when the listener deregisters itself from within an "onEvent" method.

My personal opinion is that calling "removeListener" should simply require that the specific listener's "onEvent" method will no longer be called once the listener is successfully deregistered. That definition is simple and is independent of who calls the method and what the listener might actually be doing at the time the method is called.

My proposal would be to change the behavior to no longer block, and to change the JavaDoc as follows:

Deregisters an event listener such that its <code>onEvent</code> no longer
be called.
<p>
This method has no effect if the listener is not registered at the time
this method is called.
</p>

@param listener The listener to deregister.
@throws RepositoryException If an error occurs.

Comment by jukka.zitting [ 16/Dec/13 ]

I think the reasonable interpretation of "has completed executing" in this case is that no concurrent onEvent() call is in progress.

In general I'd also prefer to simplify the method to just stop any further onEvent() calls (with an option to also truncate an EventIterator that's currently being processed); that's what I was aiming at with option 2. However I'm a bit worried about making a change that would require potential changes in both clients and implementations of the API. My wording above was intended to allow existing implementations (that do block) to remain unmodified and for a new implementation to optionally block (triggered by some custom configuration) for such clients that still require that behavior for backwards compatibility.

Comment by Peeter Piegaze [ 08/Sep/14 ]

We will have to leave this to be interpreted rationally by implementers.





[JSR_333-71] mistakes in javadoc for Node#getNodes and Event#getMixinNodeTypes ? Created: 09/Jun/13  Updated: 02/Sep/13  Resolved: 20/Aug/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: dbu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

while working on JSR_333-59 i noticed two confusing things:

Node#getNodes(String[] nameGlobs, String[] typeGlobs)

how would typeGlobs work exactly? its not really globs, right? the doc says we do Node.isNodeType(T) but that method does not accept globs. i guess that second parameter is simple typeNames, right?

Event#getMixinNodeTypes (and also getPrimaryNodeType) do not list the PROPERTY_CHANGED event as being able to return this information. is this on purpose or an accident? if its on purpose, i propose to add something explaining why it should not work.



 Comments   
Comment by Peeter Piegaze [ 20/Aug/13 ]

You are right about the Event#getMixinTypes and Event#getPrimaryNodeType. They should both include explanations of what is returned when this Event is PROPERTY_CHANGED. I have fixed the javadoc.

Regarding the typeGlobs issue: For an accessible node N to be returned, the typeGlob string is required to match T where T is the name of a type that applies to N, and the nameGlob string is required to match C, where C is the name of N.

By "match" we mean "match by globbing", not "is equal to". I will clarify the language in the javadoc.

Comment by Peeter Piegaze [ 20/Aug/13 ]

fixed

Comment by dbu [ 02/Sep/13 ]

added to PHPCR in https://github.com/phpcr/phpcr/pull/72





[JSR_333-72] Deal with the "PHP in a JSR" issue Created: 30/Jul/13  Updated: 21/Aug/13  Resolved: 21/Aug/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

We have received some feedback concerning the fact that there is PHP code inside the JSR package and that this somehow violates the rules of the JCP. I do not think that it does violate the rules but we may need to thow in some disclaimers here and there like "this is only additional documentaion, any similarlity to actual PHP code is entirely coincidental"



 Comments   
Comment by Peeter Piegaze [ 30/Jul/13 ]

Ok, so after some discussion with Werner Kiel, who is involved in the JCP, we will take his advice and remove the actual php directory from the spec zip. Instead we will reference the github URL in the PHPCR section of the spec doc.

Comment by Peeter Piegaze [ 21/Aug/13 ]

PHPCR is now referenced from within the spec document, but no PHP code is included in the actual spec package.





[JSR_333-73] Clean up editoiral comments at end of spec docu Created: 30/Jul/13  Updated: 21/Aug/13  Resolved: 21/Aug/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There are a few highighted editorial comments at the end of the spec doc. These should be cleaned up.



 Comments   
Comment by Peeter Piegaze [ 21/Aug/13 ]

fixed.





[JSR_333-59] synchronize PHPCR to JCR Created: 24/Oct/12  Updated: 21/Aug/13  Resolved: 21/Aug/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major
Reporter: dbu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by JSR_333-36 PHPCR comments doc needs some languag... Closed

 Description   

we should go through all changes between JCR 2.0 and JCR 2.1 and make sure PHPCR is missing none of them.

the PHP interfaces code is mostly done against 2.0.

Questions:

  • Is there some sort of comprehensive changelog to be found somewhere?
  • Where is the current JCR code located? the download on the jsr page is very outdated.


 Comments   
Comment by Peeter Piegaze [ 24/Oct/12 ]

The project is hosted at java.net, here:

http://java.net/projects/jsr-333/

283 is here: http://java.net/projects/jsr-333/

The latest version is in their svn here:

https://svn.java.net/svn/jsr-333~svn

for comparison 283 is here: https://svn.java.net/svn/jsr-283~svn

I agree we should review the changes and make sure PHPCR is aligned.

I will produce a diff for both the spec doc and the src files and then we can review them.

Comment by Peeter Piegaze [ 24/Oct/12 ]

sorry, the java.net projet page for 283 is obviously

http://java.net/projects/jsr-283/

Comment by Peeter Piegaze [ 05/Nov/12 ]

I have re-arranged the JSR-33 svn repo layout a bit to include a direct svn:external to the PHPCR trunk on github (luckily github provides transparent read-only svn access

This will simplify the process of building the final zip package for submission to Oracle, since we can just pull it all from the JSR-33 repo.

Next step: Make sure all changes made for 333 are included in the PHPCR.

Comment by Peeter Piegaze [ 20/Nov/12 ]

Ok, I have gone through the Java and PHP APIs
Here are the differences I found that have not yet been made.
They are expressed as changes needed to align PHPCR with JCR

ItemInterface
- refresh
+ revert

NamespaceRegistryInterface
- unregisterNamespace
+ unregisterNamespaceByURI

NodeInterface
+ addNodeAutoNamed
+ getNodeNames
+ getPropertyAs
+ getPropertyAsString
+ getPropertyAsStringArray
+ getPropertyWithDefault
+ rename
+ setMixins

+ RepositoryManagerInterface (new interface)

SessionInterface
+ getNode(absPath, depthHint)
+ getProperties

WorkspaceInterface
+ removeItem

NodeTypeInterface
+ getSupertypeNames

+ EventFilter (new interface)

ObservatiomManager
- addEventLister(eventTypes, absPath, etc...)
- getEventJournal(eventTypes, absPath, etc...)
+ addEventLister(EventFilter)
+ getEventJournal(EventFilter)

Can you guys take a look at these differences and make the required changes?

Comment by dbu [ 21/Nov/12 ]

thanks for this summary, this helps a lot!

some questions:

ItemInterface

  • refresh
    + revert

we had a real hard time and still have bugs with refresh i think. but session.refresh is kept with the same semantics as it was, correct? revert is just a replacement refresh(false) method?

NodeInterface
+ getPropertyAs
+ getPropertyAsString
+ getPropertyAsStringArray

i think we can pass on those in php

+ getPropertyWithDefault

this however sounds useful. if we have no clash, we should just add an optional parameter to getProperty

+ rename
this is just syntactic sugar for the move operation where the path does not change, right?

Comment by dbu [ 28/Nov/12 ]

started working on this: https://github.com/phpcr/phpcr/pull/52

one minor thing i noticed is that the timeoutHint versus timeOutHint is inconsistent in LockInfo versus the lock method. maybe you want to fix that in java? i kept using timeoutHint as the older things had it.

Comment by Peeter Piegaze [ 29/Nov/12 ]

Ok, I will look into that.

Comment by dbu [ 03/Dec/12 ]

the PR over at PHPCR github is now ready to be merged.

are there any further adjustments or changes planned or even possible? if so we would need to keep track of them / be notified.

Comment by Peeter Piegaze [ 04/Dec/12 ]

Thanks!

I will look over everything in the next couple days, so maybe hold off on merging for the moment. I will let you know asap. Of course if we miss something or something new and important comes up I will make sure to inform you.

Thanks again for the contribution.

Comment by Peeter Piegaze [ 20/Feb/13 ]

Apologies for the hiatus...@dbu has this been merged since the last discussion on this thread?

Comment by dbu [ 20/Feb/13 ]

yes, we merged it a while ago. but you can still see the diff in the pull request on github. feedback is still welcome.

we are currently discussing a few small adjustments in https://github.com/phpcr/phpcr/pull/54

regarding releasing PHPCR 2.1 we assume we wait until all JCR 2.1 is released as final. any ETA for that?

Comment by dbu [ 25/Apr/13 ]

unless there where new additions to jcr since ~ 15 november 2012 this issue can be closed.

Comment by dbu [ 15/May/13 ]

there are things added since november that we do need to change. i created https://github.com/phpcr/phpcr/issues/65 and hope to work on this next week.

Comment by dbu [ 01/Jun/13 ]

i did the diff again and added the new methods. this is merged in https://github.com/phpcr/phpcr/pull/66

i found two issues and created https://java.net/jira/browse/JSR_333-71

Comment by Peeter Piegaze [ 21/Aug/13 ]

PHPCR is now simply referenced from within the spec document (as required by the JCP) and therefore decoupled. So, there is no need to sync anything.





[JSR_333-55] expand SQL2 (inspired by modeshape) Created: 16/Oct/12  Updated: 30/Jul/13  Resolved: 30/Jul/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

https://docs.jboss.org/author/display/MODE/Query+and+search#Queryandsearch-JCRSQLandJCRSQL2extensions

imho of importance are the following:
Removing duplicate rows with SELECT DISTINCT ...
Limit the number of rows returned with LIMIT count
Skip initial rows with OFFSET number
Constrain the depth of a node with DEPTH(selectorName)
Constrain the path of a node with PATH(selectorName)
Constrain the references from a node with REFERENCE(selectorName.property) and REFERENCE(selectorName)
Use pseudo-columns to include the path, score, node name, node local name, and node depth in result columns or in criteria



 Comments   
Comment by thomasmueller2 [ 17/Oct/12 ]

As for DISTINCT: sounds good to me.

LIMIT / OFFSET: we should consider (also) supporting the ISO SQL:2008 standard form, see also:

It's sad that the standard is so verbose.

What about UNION?

Comment by rhauch [ 17/Oct/12 ]

There's another page in the ModeShape's documentation that shows the grammar rules for our extensions to the JSR-283 JCR-SQL2 language. There are a few extensions not mentioned:

  • additional FULL OUTER JOIN and CROSS JOIN types
  • UNION, INTERESECT and EXCEPT
  • set criteria, with IN and NOT IN clauses (essentially syntactic sugar for an OR-ed set of equality criteria or an AND-ed set of non-equality criteria)
  • BETWEEN criteria (essentially syntactic sugar for two comparison criteria)
  • simple arithmetic in numeric-based criteria and ORDER BY clauses
  • non-correlated subqueries in the WHERE clause (only where a static operand can be used), where only the first column is used; this is extremely useful when used in conjunction with an IN clause
  • support for NOT LIKE (essentially syntactic sugar for wrapping a LIKE criteria in a NOT(...) clause)

The ModeShape community tries to minimize the extensions, but decided that these were extremely useful and made things much more convenient for client applications. We'd love to any (if not all) of these added to JSR-333. Some are syntactic sugar on top of existing language features (and thus are very easy to implement), while most others are relatively straightforward to implement. A few (like subqueries) were actually very straightforward for us to implement, but might not be for other implementations.

LIMIT / OFFSET: we should consider (also) supporting the ISO SQL:2008 standard form ...

That sounds good to me.

Comment by Peeter Piegaze [ 23/Oct/12 ]

Well, since looking at the Modeshape docs I realize that the spec work is basically already done (thanks Randall!). Given that, and given that Modeshape is already existence-proof of the feasibility of these additions to the query language, I would suggest that we adopt the Modeshape enhancements wholesale.

Any objections?

Comment by thomasmueller2 [ 23/Oct/12 ]

I think it would make sense to add those features. I'm wondering if some of them could / should be declared optional?

As a first step, could we extend the BNF and check what the railroad diagrams would look like?

Comment by lsmith77 [ 23/Oct/12 ]

One thing I worry about is that by adding more and more features we loose focus on making the features already available actually useable from a performance POV. F.e. JOINs are essentially useless in Jackrabbit. Sorting by a datetime is super slow etc. So rather than spend time adding even more features, I would much rather have implementors focus on key features so that they have enough time resources left to make them fast.

Speaking of JOIN performance, one big challenge of RDBMS is writing query optimizers so that queries are always executed with the optimal execution path. I think its unlikely that any JCR implementor would ever invest even remotely enough time to make a generic optimizer that performs really well. So imho it might make sense to ease the work by supporting a hint syntax. It would mean that these statements would no longer automatically adjust themselves if the data changes, but it might make some advanced features more feasible.

Comment by rhauch [ 23/Oct/12 ]

I agree that it's important to make existing features actually usable. IMO, the JSR-283 JCR-SQL2 is is less usable than you might imagine. ModeShape added these extensions not because we thought they'd be useful, but because without them we couldn't actually create many of the queries our applications needed. And for the syntactic sugar extensions, we simply got tired of writing and maintaining the longer versions of the queries.

Performance is indeed important, and implementations simply need to decide whether it's important to them to improve the performance of the more complicated queries (especially joins). We think it's very important to be able to access content independent of the hierarchy, and we've made it a priority (and will continue to make significant improvements in this area).

The challenge with making these features optional is that it will make it a bit more difficult for users to support several JCR implementations. Having said that, I understand that the different join types, set queries (unions, intersects, excepts), and subqueries might be more challenging to implement, so I understand the question about making some things optional.

Comment by lsmith77 [ 23/Oct/12 ]

We wrote an app using JOINs, found the performance to be bad with Jackrabbit and when we looked at it, we realized the only used JOINs due to an RDBMS mindset. We then refactored things into simpler queries and some middle ware code. Better performance, simpler code. To me the key thing missing is count/facetting as well as ways to interact with path/depth in an easy way.

Its even worse, since equivalent queries in the SQL2 and the old SQL syntax perform differently http://blog.liip.ch/archive/2012/06/26/jackrabbit-and-its-two-sql-languages-some-findings.html

Comment by thomasmueller2 [ 24/Oct/12 ]

> JOINs are essentially useless in Jackrabbit

Yes, I heard they are slow in Jackrabbit 2.x. As for Jackrabbit Oak, the plan is to implement them in a different way, so performance should no longer be a problem in most cases. The disadvantage is that you will need to declare indexes to speed up joins (I wonder if index metadata should be standardized?)

> Speaking of JOIN performance, one big challenge of RDBMS is writing query optimizers so that queries are always executed with the optimal execution path.

Yes.

> I think its unlikely that any JCR implementor would ever invest even remotely enough time to make a generic optimizer that performs really well.

For Jackrabbit Oak, the plan is to use a cost based optimizer. The plan is to support the nested loop join algorithm only, at least at the beginning.

I guess a bit more problematic than the optimizer will be optimizations for certain features, for example for conditions of the form X = ? OR Y = ?. In this case, the query engine could use an index on X and an index on Y, and combine the result. This is quite tricky to implement in the query engine, and having support for UNION will actually allow a user to work around such a restriction in the query engine (if there is one). So adding features sometimes even helps.

> supporting a hint syntax

Could you post an example of your preferred syntax? I think it is related to indexes, and if we support it we probably need to standardize indexes as well.

About which features should be optional: I would prefer if the following features are optional:

  • full outer joins, cross joins
  • subqueries
  • the "exclusive" option for "between" (seems to be non-standard)
  • depth(..)
  • correlated subqueries (not currently supported by ModShape)

About the following I'm not sure: "If the subquery is used in a clause that expects a single value (e.g., in a comparison), only the subquery's first row will be used." - I would rather throw an exception in this case.

"mode:localName" and "mode:depth": I'm not sure if they should not be supported, as they are simply synonyms for localname() and depth(). If we do want to support them, then we should rename them.

I would like to add an operator to concatenate text: ||

About using double quotes to quote identifiers: I think the next JCR specification should at least deprecate (if not disallow) support for double quotes for string literals.

Comment by lsmith77 [ 24/Oct/12 ]

I really wonder if investing in a cost based optimizer is really the best use of developer resources. The number of complex queries will likely be much smaller compared to an RDBMS, so I think relying on hints will likely be quite feasible.

In terms of hints i mainly see choosing an indexes (MySQL hint syntax is here http://dev.mysql.com/doc/refman/5.6/en/index-hints.html), but also join order (MySQL has STRAIGHT_JOIN for this).

+1 on concat

Comment by rhauch [ 24/Oct/12 ]

ModeShape also has some work to incorporate a cost-based optimizer and other significant improvements in query engine capability to support far larger result sets, more efficient join algorithms, etc. Fast, efficient, and powerful queries are an important goal for us.

Comment by Peeter Piegaze [ 20/Feb/13 ]

I'll start incorporating the modeshape stuff into the spec, according to the discussion above, esp. Thomas;'s specific points. Also I will add the concat.

Comment by rhauch [ 16/May/13 ]

I generally agree with Thomas' comments, including those about which features might be optional. In particular, both correlated and non-correlated subqueries should be optional. (For the record, we added support for non-correlated because we needed better ways of dynamically specifying a range of values for criteria. I'm not sure when/if we'll support correlated.)

> "mode:localName" and "mode:depth": I'm not sure if they should not be supported, as they are simply synonyms for localname() and depth(). If we do want to support them, then we should rename them.

+1 for renaming them. We would have used "jcr:localName" and "jcr:depth", except we didn't want to start expanding the "jcr" namespace with custom extensions. We can very easily support the new and old names at the same time, should these be added to JSR-333.

> I would like to add an operator to concatenate text: ||

+1

> About using double quotes to quote identifiers: I think the next JCR specification should at least deprecate (if not disallow) support for double quotes for string literals.

I'm fine with deprecating, but I would argue against disallowing it since JSR-333 will be a point release (e.g., 2.1) and IMO any queries that were allowed in 2.0 should be allowed in 2.1.

Comment by reschke [ 16/May/13 ]

This would need to be added to JQOM as well, right?

Comment by rhauch [ 21/May/13 ]

Yes. You can see the ModeShape API extensions in our JavaDoc and codebase. Although the Java interfaces in the 'org.modeshape.jcr.api.query.qom' package are currently licensed with LGPL 2, all of the people that modified those interfaces would be happy to contribute all or parts of them to JSR-333. (After all, they are just interfaces.)

Comment by Peeter Piegaze [ 30/Jul/13 ]

So we have just passed the public review. The next step is to fix up a few smallish bugs and submit the "proposed final draft". There are about 4-5 small bugs, and then there is this one

At this point in the process, and given my own workload (and my employer's priorities wrt that) I have to say that I cannot see putting the modeshape stuff into the spec.

So, unless someone volunteers to do the work, and do it well, and to do it relatively quickly (that includes changes in the spec document itself as well) I am going to to have to WONTFIX this one. Sorry.

Re-open if you are serious about taking on this job

Comment by Peeter Piegaze [ 30/Jul/13 ]

WONTFIX due to resource_constraint@ppiegaze





[JSR_333-70] 10.8.3 Updating Nodes Across Workspaces - clarify behaviour with mix:versionable Created: 29/Apr/13  Updated: 24/May/13  Resolved: 23/May/13

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: dbu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

discussing with jukka, we realized that updating a node from a clone in a different workspace skips children that are mix:versionable (should be simpleVersionable actually, see https://issues.apache.org/jira/browse/JCR-3585).

we found nothing in the spec that explains this. i think its useful behaviour and could be clarified in section 10.8.3

http://www.day.com/specs/jcr/2.0/10_Writing.html#10.8.3%20Updating%20Nodes%20Across%20Workspaces



 Comments   
Comment by Peeter Piegaze [ 16/May/13 ]

Yep, ok. I will put this in the spec and the javadoc.

But, just remind me why this is reasonable behaviour?

Comment by dbu [ 22/May/13 ]

we tried to build a publish workflow with the clone / update functionality. we have a node that represents a page. some child nodes are parts of that page. other child nodes represent child pages. the publish workflow should affect the page and all its element, but not its children.

Comment by Peeter Piegaze [ 23/May/13 ]

So, currently jackrabbit skips direct children if they are mix:versionable (but this should be mix:simpleVersionable) but it does not skip deeper mix:versionables within the subtree, is that correct?

Comment by Peeter Piegaze [ 23/May/13 ]

I have changed the description of Node.update to the following

If this node does have a corresponding node in the workspace srcWorkspace, then this method does the following:

  • Deletes all properties from this node.
  • Copies over all properties from the corresponding node.
  • Deletes all child nodes (and their subtrees) of this node that are not of type mix:simpleVersionable (or one of its subtypes, including mix:versionable).
  • Copies over all child nodes (and their subtrees) from the corresponding node that are not of type mix:simpleVersionable (or one of its subtypes, including mix:versionable).
Comment by fazy [ 24/May/13 ]

"So, currently jackrabbit skips direct children if they are mix:versionable (but this should be mix:simpleVersionable) but it does not skip deeper mix:versionables within the subtree, is that correct?"

Actually, I have had trouble producing/observing this behaviour (Jackrabbit 2.6):

https://issues.apache.org/jira/browse/JCR-3593

Comment by fazy [ 24/May/13 ]

Just another thing; I wonder if this behaviour merits its own mixin type, rather than mixing the functionality with mix:(simple)versionable?

(I think) mix:versionable already implies mix:referenceable, which makes sense, but should it also imply a change in how updates are cascaded?

Perhaps it would be better to introduce a new type, mix:updateCascade (or the opposite, mix:updateNoCascade might be necessary for backwards compatibility). That way, there is no need to define versionable nodes if versioning is not being used (or not supported) in order to get this behaviour.





[JSR_333-63] Provide the [property|node]Type information in Event objets Created: 30/Nov/12  Updated: 25/Apr/13  Resolved: 25/Apr/13

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Timothee Maret Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When using Observation, it is useful to filter out events based on the [node|property]Type of the resource at Event#getPath().

The mechanism to add Event listener allow filtering on nodeTypes but only on parent nodes. Thus, it quickly becomes necessary to load the the referenced node from the repository in order to filter it.
In cases where most of the events are filtered out ultimately, we would have wasted quite some time to load nodes for nothing.

In order to avoid loading unneeded nodes, It may make sense to add the nodeType and propertyType information right into the Event.

Two possibilities to enable that:

1. Adding the method: "String Event#getItemType()" to the Event API.
2. Pass the type information by default as a field in the info Map, retrieved through Event#getInfo() and document it



 Comments   
Comment by Peeter Piegaze [ 20/Feb/13 ]

@reschke, do you have an opinion on this.

Anyone?

Comment by Peeter Piegaze [ 25/Apr/13 ]

I have added the following methods in spec and src:

Event.getPrimaryNodeType()
Event.getMixinTypes()
Event.getPropertyType()

The details are explained in the Event interface javadoc and the Observation section of the spec.





[JSR_333-68] Specification is not clear on semantics of removing version histories Created: 06/Mar/13  Updated: 23/Apr/13  Resolved: 23/Apr/13

Status: Resolved
Project: jsr-333
Component/s: api, spec
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: rhauch Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Section 15.8 of the JSR-283 specification covers removal of specific versions within a version history. However, I'm unable to find any information in the spec about removing entire version histories. There certainly may be regulatory and policy reasons for preventing the removal of some data, but likewise there may be regulatory and policy reasons for removing all store data relating to some particular topic. IMO, a repository implementation can provide the tools to allow both, but cannot choose one specific behavior. We have to allow applications to implement their own policies and behavior, and thus it needs to be addressed in the specification and possible API if there are changes to JavaDoc and/or interfaces.

The other problem with removing only the versions is that it is likely that the root version remain. Thus, when frequently creating, modifying and removing versionable nodes, the amount of version history storage will continue to increase and cannot be compacted (at least through activities instigated by standard API calls).

So I think there are a couple of issues.

  1. Once a node is removed, it is not possible to find the version history. That's because the VersionManager.getVersionHistory(...) takes the path of the versionable node. Thus a client can only find a version history for a removed node only if it somehow remembers the path. Plus, I would suspect that most implementations do not store version histories based upon the path, but rather the identifier. Should we change the JavaDoc on method to explicitly say identifier paths are accepted, or should we add VersionManager.getVersionHistoryById(String versionableId)? (Yes, a client still needs to know the identifier, but at least that is durable.)
  2. Removing version histories is complicated by the fact that multiple workspaces may have corresponding versionable nodes. Thus, removal of a versionable node from one workspace does not mean the version history is no longer used. However, if no other workspace has a corresponding versionable node, then it should be possible to completely remove a version history. Currently the TCK tests check that this is not permitted, because it checks that Item.remove() does not work on a VersionHistory node. Considering that the spec defines an explicit way to remove Version nodes (rather than allow Item.remove() to work), we should add a VersionManager.removeVersionHistory(String path) (and based on #1 above perhaps also a VersionManager.removeVersionHistoryById(String versionableId. These methods should fail if there is a versionable node with that identifier in at least one workspace.
  3. What happens to the version history when a versionable node is made to be no longer be versionable? For example, if a node is versionable only because it explicitly has "mix:versionable" in the list of mixin types, what happens when "mix:versionable" is removed from the node (assuming the version history was already created prior to this)? Is the version history even valid anymore? Can an older version be restored to a node that is no longer versionable? (If not, then we need to clarify this in the section that talks about restoring.)
  4. *Does it make sense to add "Node.remove(boolean removeVersionHistories)", so that a subgraph (of 1 or more potentially versionable nodes) can be removed and their version histories be removed at the same time (assuming the version histories can be removed because there are no corresponding nodes in other workspaces)?


 Comments   
Comment by Peeter Piegaze [ 10/Apr/13 ]

The getXXXById methods are not really needed, since you can always pass a JCR path in identifier-based form, e.g.:

[f81d4fae-7dec-11d0-a765-00a0c91e6bf6]

See section 3.4.4. I am pretty sure you are supposed to be able to pass any kind of path to any method, so this should work already.

So this leaves the suggestion to add VersionManager.removeVersionHistory(String path) and
Node.remove(boolean removeVersionHistories)

I guess I don't have an objection to adding these, but what exactly is wrong with leaving this up to the implemention anyway? Isn't it pretty much impl-sensitive or at least "policy-sensitive" in the first place. Do we nee to put it in the spec?

Comment by rhauch [ 10/Apr/13 ]

In 1) above I suggest that the JavaDoc be amended to say that identifier paths are also accepted.

Regarding 3): it would be nice to see some clarification in the spec about this, or even some feedback here. Perhaps it's something that hasn't really been considered. IIUC, even the reference implementation does not provide a way of completely removing the version history for a node - there is always something left, even after removing all versions in a given history. For example, create 1M versionable nodes (and check them in), then remove all of those nodes and remove all of the versions from their histories, and version storage will still contain 1M almost empty version histories.

Are you suggesting that implementations could implement Version.remove() and VersionHistory.remove()? As it stands now, the TCK tests check that these methods always throw an exception, so implementation cannot vary this behavior and fully pass the TCK. Perhaps it is a TCK error, in which case I can log it accordingly.

I agree that removing version histories is "policy-sensitive", but no more so than removing versions. In fact, not providing a way to remove entire version histories seems to be assuming some policy. Currently there is no API-compatible way to even allow client applications to completely remove histories, so even if a client application had a policy that allowed removing data, there's no way for them to do it.

Comment by Peeter Piegaze [ 23/Apr/13 ]

For

VersionManager.getVersionHistory(String absPath)

I have added a note in spec and javadoc clarifying that when a JCR path is passed if may be an "identifier-based absolute path" as defined in in spec section 3.4.4.1.2 and that a version without a corresponding versionable should still be maintained (and be accessible by the versionables identifier).

I have also added the method

void VersionManager.removeVersionHistory(String absPath)

which (in those impl that support it) removes the VH as long as that VH has no exiting verisonables in any WS.

Regarding the idea Node.remove(boolean removeVersionHistories):
I don't think this is a good idea, since VH removal is a rather "big deal" and I don't hink it belongs aas flag on something as common as node removal.

Comment by rhauch [ 23/Apr/13 ]

Thanks, Peeter. Your changes sound good, and I'm okay with not including the "Node.remove(boolean)" method.





[JSR_333-43] Event does not provide sufficient information for multiplexing events into a single stream Created: 14/Nov/11  Updated: 22/Apr/13  Resolved: 22/Apr/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: reschke Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When providing remote access to a JCR store, it may be good for performance to create a single stream of observation events, and to filter/route them on the client side.

To be able to do that, the Event object should provide information about the primary node type and the mixin node types of each event (with semantics similar to those specified in the API for creating the event listener).



 Comments   
Comment by rhauch [ 14/Nov/11 ]

Adding the primary node type and mixin node types to every event will add significantly to the size of the events, which when sent across the network will compound the expense and latency for clustered repositories or for those with lots of remote clients. Additionally, there will be a fair amount of duplicate information for multiple property events on the same node.

Comment by reschke [ 14/Nov/11 ]

Well, it's up to the code that sends the events over the wire to decide whether to include the node type information or not, right?

Comment by rhauch [ 14/Nov/11 ]

True, an implementation can decide whether it sends the information over the wire from where the event is being generated, or to not send the information over the wire and have the recipients (whether they be clients or other processes in the cluster) must then look up every recently changed node to discover the primary type and mixin types.

Note that at the current time, the primary type and mixin types are only required when there are observers registered with node type filters. In all other cases, the primary type and mixin type information is not needed.

But IIUC, the proposed change is to add the primary type and mixin type to every event, which means the sending or looking up of the primary type and mixin type information would become mandatory and would have a negative impact on performance.

Comment by reschke [ 14/Nov/11 ]

That's indeed a problem. Sounds like the party starting the observation needs to state what it wants.

Comment by thomasmueller2 [ 14/Nov/11 ]

I wonder what mixin types to return if the node type were changed: the old mixin types, the new mixin types, or both (using two events).

> the proposed change is to add the primary type and mixin type to every event, which means the sending or looking up of the primary type and mixin type information would become mandatory

Is that really the case? Let's say if we add NodeType Event.getPrimaryNodeType(). It could be implemented as follows:

return getNodeInternal(getPath(), revision).getPrimaryNodeType();

(or something like that).

Comment by reschke [ 14/Nov/11 ]

Thomas, that doesn't work for NODE_REMOVE events.

Comment by rhauch [ 14/Nov/11 ]

> > the proposed change is to add the primary type and mixin type to every event, which means the sending or looking up of the primary type and mixin type information would become mandatory
>
> Is that really the case? Let's say if we add NodeType Event.getPrimaryNodeType(). It could be implemented as follows:
>
> return getNodeInternal(getPath(), revision).getPrimaryNodeType();
>
> (or something like that).

Ah, it's true that looking up the primary type and mixin type information can be done lazily. Forgive my ignorance for not realizing the obvious.

Comment by Peeter Piegaze [ 16/Oct/12 ]

So, if we add methods:

String Event.getPrimaryNodeType()
String[] Event.getMixinNodeTypes()

In all cases except NODE_REMOVE, the implementation is trivial, amounting to a convenience method. The only case in which new otherwise inaccessible information is provided is the case of NODE_REMOVE. Is the implementation burden in that case to heaby to justify the addition of thse methods?

Comment by Peeter Piegaze [ 19/Feb/13 ]

Unless someone objects, I will go ahead and make the changes I mention above.

Comment by stefan_guggisberg [ 19/Feb/13 ]

Unless someone objects, I will go ahead and make the changes I mention above.

-1. i agree with randall's objections, i.e.

But IIUC, the proposed change is to add the primary type and mixin type to every event, which means the sending or looking up of the primary type and mixin type information would become mandatory and would have a negative impact on performance.

Comment by Peeter Piegaze [ 20/Feb/13 ]

@Stefan: And Thomas's example doesn't help?

>> the proposed change is to add the primary type and mixin type to every event, which means the sending or looking
>> up of the primary type and mixin type information would become mandatory
>
> Is that really the case? Let's say if we add NodeType Event.getPrimaryNodeType(). It could be implemented as follows:
>
> return getNodeInternal(getPath(), revision).getPrimaryNodeType();
>
> (or something like that).

Comment by stefan_guggisberg [ 20/Feb/13 ]

@Stefan: And Thomas's example doesn't help?

whether the node type information is part of an event's payload or retrieved lazily is IMO an implementation detail.

i still don't see a compelling use case for adding node type information to the event.
the initially mentioned use case (remoted/client filtered observation) could be just as well
implemented without extending the Event interface. it's an implementation detail what
kind of information is sent over the wire. the server can e.g. send node type information
over the wire which is filtered on the client.

Comment by thomasmueller2 [ 20/Feb/13 ]

I agree with Stefan.

Maybe we should first get more info from Julian Reschke. I don't understand the use case either, and how it would help "multiplexing events into a single stream".

Julian later wrote "that doesn't work for NODE_REMOVE", so maybe the use case actually is getting more info for NODE_REMOVED events?

Comment by rhauch [ 20/Feb/13 ]

thomasmueller2 wrote:

Julian later wrote "that doesn't work for NODE_REMOVE", so maybe the use case actually is getting more info for NODE_REMOVED events?

But doesn't the node type name apply to the parents for NODE_REMOVE? The spec allows impls to generate NODE_REMOVED events only for the top-level node of a removed subgraph, which means the (former) parent should still exist.

Comment by Peeter Piegaze [ 22/Apr/13 ]

Since we are trying to submit for public review ASAP I am resolving this bug as WONT-FIX for lack of interest.

If sufficient interest arises later, we can create a new Public Review bug for this issue.





[JSR_333-20] Add aggregation support for queries Created: 08/Dec/10  Updated: 22/Apr/13  Resolved: 22/Apr/13

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: current
Fix Version/s: milestone 1

Type: New Feature Priority: Major
Reporter: mduerig Assignee: Peeter Piegaze
Resolution: Won't Fix Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 20

 Description   

There should be at least basic support for aggregation in queries (i.e. count).

Currently the number of results of a query are available from the NodeIterator
returned by QueryResult#getNodes(). However since implementations are free to
return -1 if the number of elements is not available this method is not reliable.

IMO the current approach mixes two concerns: querying for nodes and querying for
the number of nodes satisfying the query condition. This is particularly
problematic since users might not be interested in both but still encounter any
performance impediment from calculating the other.



 Comments   
Comment by Peeter Piegaze [ 04/May/11 ]

Do you have a proposal on how to fix this?

Comment by thomasmueller2 [ 05/May/11 ]

The standard way in SQL "select count from ..."

P.S. I believe Michael is on vacation until May 15th.

Comment by lsmith77 [ 16/Oct/12 ]

yes .. however i think we may even want to go further and define how facetting is to be supported as an optional feature. but of course such "virtual" nodes do not fit well with the current standard.

Comment by Peeter Piegaze [ 20/Feb/13 ]

Does anyone have any more detailed ideas on this?

Comment by Peeter Piegaze [ 22/Apr/13 ]

Since we want to submit for public reveiew ASAP and have only a few issues left to resolve I am closing this as WONT-FIX due to lack of interest. If sufficient interest re-appeears, we can make this Public review bug





[JSR_333-69] Change semantics of name globbing in Node.getNodes and friends Created: 21/Mar/13  Updated: 22/Apr/13  Resolved: 22/Apr/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In the methods Node.getNodes(String namePattern), Node.getNodes(String[] nameGlobs) and the related getProperties, getNodeNames getNodeByType the globbing patterns are described (at least in the spec, section 5.2.2.1 Name Pattern) as matching only the qualified form of the node or property name.

However, in 3.2.6 Use of Qualified and Expanded Names, it states that JCR names may be passed in either form. In fact an important part of introducing expanded form was to make it transparent to the API

Though this does not strictly contradict the behavior of the matching methods, since the params are matching strings, not JCR names, it certainly violates the spirit of the rule.

I propose to re-spec the methods so that matching is done against both qualified and expanded forms of the candidiate JCR names.



 Comments   
Comment by Peeter Piegaze [ 21/Mar/13 ]

This issue arose because I had spec'd Node.getNodesByType to match both qualified and expanded names of node types. So, alternatively I could just change that to match qualified names only. This would be less disruptive but technically sort of "wrong"

Comment by Peeter Piegaze [ 22/Apr/13 ]

The Node methods getNodes, getNodeNames and getProperties that take glob pattern String arrays are now spec'd such that globbing will match both qualified and expanded forms of a name.





[JSR_333-51] Uniqueness extension for property definition Created: 09/Aug/12  Updated: 10/Apr/13  Resolved: 10/Apr/13

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor
Reporter: anchela Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: checklater

 Description   

the property definition of jcr:uuid on mix:referenceable is currently as follows:

  • jcr:uuid (STRING) mandatory autocreated protected INITIALIZE

the specification in addition mandates the values of jcr:uuid properties
that have this property definition to be unique within a given workspace but
that constraint is not expressed in the node type definition.

imo it might make sense to extend the property definition by an additional
flag indicating such a uniqueness constraint. jcr implementations that cannot
enforce uniqueness of property values would subsequently not allow to have
node types registered containing property definitions with that attribute
being set.

proposed change for the cnd:

/* The property attributes are indicated by the presence or
absence of keywords. */
PropertyAttribute ::= Autocreated | Mandatory | Protected |
Opv | Multiple | QueryOps | NoFullText |
NoQueryOrder | Unique

/* If 'unique' is present without a '?' then the property values
are enforced to be unique within a given workspace. If 'unique'
is present with a '?' then the unique status is a variant. If
'unique' is absent then no uniqueness constraint applies. */
Unique ::= ('unique' | 'uni' | 'u' )['?']

proposed new method for PropertyDefinition.java

/**

  • Reports whether the value of this property is to be unique with a given
  • workspace. If <code>true</code>, then this <code>PropertyDefinition</code>
  • will necessarily not be a residual set definition but will specify an
  • actual item name (in other words getName() will not return "*").
  • <p>
  • Implementations that cannot enforce unique constraints on properties
  • will support node type registration with <code>PropertyDefinitionTemplate</code>
  • having this flag set.
  • @return a <code>boolean</code>.
    */
    public boolean isUnique();

proposed change on PropertyDefinitionTemplate:

/**

  • Sets the uniqueness status of the property.
    *
  • @param unique a <code>boolean</code>.
    */
    public void setUnique(boolean unique);


 Comments   
Comment by Peeter Piegaze [ 20/Feb/13 ]

Does anyone object to this idea?

Comment by Peeter Piegaze [ 02/Apr/13 ]

Would this apply to:

  • all properties of the same name within a workspace, or
  • all properties of the same name explictly declared in any node type, or
  • all properties ofthe same name explicitly declared in the same node type?

Would it apply to client-settable properties or just system-initialized ones?

If it applies to client-settable properties, we would have to exempt large strings and binaries (and booleans correct?

Comment by rhauch [ 02/Apr/13 ]

This feature sounds useful, at least in theory. But I'm not sure how we might go about implementing it in an eventually consistent implementation or in a strongly-consistent implementation. We can't rely upon the same indexes that the query system uses, since they don't include any transient state. And this would seem to add a lot of processing overhead when a session has a very large number of transient changes (e.g., hundreds of thousands of new nodes).

Comment by Peeter Piegaze [ 04/Apr/13 ]

I think that for this feature to be realistically implementable it would have to have to include so many exemptions that it would not be worth it. Basically the uniqueness of the node ID is really the case I can see where this would apply.

For this reason I suggest we resolve this as WONTFIX. Unless someone can convince me otherwise





[JSR_333-14] Checked versus unchecked exceptions Created: 26/Sep/10  Updated: 02/Apr/13  Resolved: 02/Apr/13

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: uncled Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 14
Tags: checklater

 Description   

Generally there are a lot of checked exceptions throughout the API. It may be worth thinking about
introducing more unchecked exceptions, potentially even extending RepositoryException from
RuntimeException. Thoughts?



 Comments   
Comment by uncled [ 26/Sep/10 ]

changing component

Comment by rhauch [ 27/Sep/10 ]

I would love to see all checked exceptions changed to runtime exceptions, though they still need to be
documented and (preferably) included on the throws clauses.

Comment by thomasmueller2 [ 16/Jan/11 ]

For me, the motivation is ease of use (the users of the API will no longer need
to catch or re-throw the exception), but we need to discuss the advantages /
disadvantages.

We need to investigate whether or not this does break compatibility. I guess in
theory it does break compatibility, but I'm not sure about the consequences in
practice for existing code. As it was and is done for similar changes in the
Java language or API, we could define a source code corpus (similar to the
http://qualitascorpus.com/) that allows us to verify if it does in fact break
compatibility.

Comment by reschke [ 17/Jan/11 ]

"Ease of use" sounds subjective to me.

I personally hate it when I don't know what needs catching (Hibernate...).

It appears that we're planning for 180 degree turn; maybe we should start
identifying a problem (such as lookups throwing exception instead of returning
null?).

Comment by thomasmueller2 [ 17/Jan/11 ]

> I personally hate it when I don't know what needs catching (Hibernate...).

Runtime versus checked exceptions is very subjective. Most programming languages
don't have checked exceptions at all (for example, C# and Scala don't have
them). For me, checked exceptions are more a nuisance than a help, specially if
each and every method in an API can throw an exception, or even worse, multiple
exceptions. As a user of the API, I have to catch or re-throw the exception,
even thought I can't possibly do much about it. As an example,
Session.getRootNode() can throw a RepositoryException. Most likely this is my
mistake because I closed the repository already. This situation is somewhat
similar to NullPointerException (which is unchecked). Another possible reason
is: the connection to the repository or backend store is lost, which is not
really preventable or recoverable. See also
http://stackoverflow.com/questions/2884836/why-nullpointerexception-is-a-runtime-exception-and-remoteexception-not

> lookups throwing exception instead of returning null

Yes, this would sound like a problem.

Comment by Peeter Piegaze [ 02/Oct/12 ]

So, just for the sake of argument. If we were to do this, it would involve changing RepositoryException from

public class RepositoryException extends Exception

to

public class RepositoryException extends RuntimeException

Is that it?

And what impact would this have on existing code that uses the JCR API?

Comment by Peeter Piegaze [ 19/Feb/13 ]

I am inclined to make this change. It would seem to be one of the most significant things we could do to actually make the API easier to use, and that is supposed to be one of the goals of JSR-333.

Would it make sense to keep some of the exceptions as checked and change only those that truly meet some criteria (non-religious, hopefully) that we decide upon?

Any ideas?

Comment by Peeter Piegaze [ 02/Apr/13 ]

Fixed.

RepositoryException.java:
- public class RepositoryException extends Exception
+ public class RepositoryException extends RuntimeException




[JSR_333-65] Credential implementations should implement hashCode() Created: 07/Dec/12  Updated: 02/Apr/13  Resolved: 02/Apr/13

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: rhauch Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JCR's javax.jcr.Credentials implementation classes do not provide their own hashCode() methods. These are not terribly useful on Credentials implementations, but when they are the currently instance-based inherited implementations makes them less useful. (The only use case I've encountered is when an object containing them, such as in a JCA implementation of ConnectionRequestInfo, must implement equality and hash code semantics.)

An implementation of 'hashCode' added to the SimpleCredentials class should be based solely on the userID field (and not the password) to avoid leaking anything about the internal password:

/**
 * Returns a hash code value for this credentials, based entirely on the {@link #getUserID() user ID} field.
 * @return  a hash code value for this object.
 */
@Override
public int hashCode() {
    return userID.hashCode();
}

@Override
public boolean equals(Object obj) {
    return this == obj;
}

Note that I included an implementation of equals(Object) that is identical to the Object.equals(Object) implementation. The semantics of these two methods are bound together, and thus it is often best practice to implement both if implementing either one.

Meanwhile, because all GuestCredentials are equivalent, its implementation can always return the same value:

/**
 * All instances of GuestCredentials are considered equal and therefore have the same hash code.
 * @return  a hash code value for this object.
 */
@Override
public int hashCode() {
    return 41; // a prime number
}

/**
 * All instances of GuestCredentials are considered equal.
 * @param   obj   the reference object with which to compare.
 * @return  <code>true</code> if this object is the same as the obj
 *          argument; <code>false</code> otherwise.
 */
@Override
public void equals( Object obj ) {
    return obj == this || obj instanceof GuestCredentials;
}


 Comments   
Comment by Peeter Piegaze [ 20/Feb/13 ]

Anyone object to this?

Comment by Peeter Piegaze [ 02/Apr/13 ]

Methods added as suggested. SimplCredentials.equals override corrected to return boolean.





[JSR_333-49] Add ability to cancel queries Created: 25/Jun/12  Updated: 02/Apr/13  Resolved: 02/Apr/13

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: rhauch Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Provide a way for an executing query to be cancelled. This is likely only applicable to long-running queries, and the query would have to be cancelled in a separate thread (meaning the client would have to provide a way of holding onto and managing the queries). However, without this functionality it is currently not possible to stop an expensive (perhaps very long-running) query. Note that complex JCR-SQL2 queries coupled with very large (distributed) repositories can indeed create long-running queries.

The following is the suggested JavaDoc for the new method that is to be added to the 'javax.jcr.query.Query' interface:

/**

  • Signal that the query, if currently {@link Query#execute() executing}

    , should be cancelled and stopped (with an exception).

  • This method does not block until the query is actually stopped.
  • @return true if the query was executing and will be cancelled, or false if the query could not be cancelled
  • because it had either already finished executing, it had already been cancelled, or the implementation
  • doesn't support canceling queries.
  • @since 2.1
    */
    public boolean cancel();

Feedback and discussion welcomed!



 Comments   
Comment by thomasmueller2 [ 25/Jun/12 ]

This would be similar to the JDBC method java.sql.Statement.cancel(), right?

To avoid adding a new method, what if Session.logout() would have the semantics of such a cancel() method, if such a feature is available? Of course that would make the session unusable, not sure if that's a big problem.

Comment by rhauch [ 25/Jun/12 ]

Yes, it would be similar to java.sql.Statement.cancel().

I did consider forcibly closing the session rather than introducing a new method, but such an approach seemed too heavy-handed and IMO made the semantics of the Session far more complex - almost at any time the Session might be closed by another thread. Most applications don't have to worry about this because Sessions are generally tolerant of all kinds of issues (even connectivity issues), which means the application's cached and transiently-modified state is not at risk.

So I concluded that the best way for the specification to allow clients to explicitly cancel long-running, poorly-performing, or far-too-intensive queries is to have a method that does exactly this. I did pattern this after java.sql.Statement.cancel(), although I thought a bit more feedback would be helpful (thus the return parameter). Plus, some implementations could always return false if they didn't support canceling queries.

One benefit of this approach is that the semantics and behavior of Query.execute() remains nearly unchanged: the JCR client doesn't have to modify any code because they already have to catch RepositoryException to handle any errors that occur during execution. Canceling the execution of a query is just one additional potential error.

Note that it might be beneficial to add a new QueryCancelledException subclass of RepositoryException so that clients know about (and perhaps handle in a special way) when the execution was explicitly canceled. Again, this would not change the signature of the existing Query.execute() method.

Comment by rhauch [ 25/Jun/12 ]

Updated the proposed JavaDoc to explicitly state that an implementation could always return 'false' if it did not support canceling queries.

Comment by thomasmueller2 [ 17/Oct/12 ]

Another alternative might be a way to specify a query timeout, similar to java.sql.Statement.setQueryTimeout(int seconds), set via SimpleCredentials.setAttribute. But I'm not sure if it's a good solution.

Comment by thomasmueller2 [ 17/Oct/12 ]

In many cases an administrator (and not the person / program who ran the query) should have a way to list currently running queries and stop them if necessary.

Instead of using the JCR API, probably it would make sense to use JMX for such tasks.

Comment by Peeter Piegaze [ 20/Feb/13 ]

Unless someone objects, I will go ahead and make this change

Comment by Peeter Piegaze [ 25/Mar/13 ]

I have added the following method to Query

/**
     * This method is used from another thread to halt a currently executing query.
     * This method returns immediately with a boolean return value indicating whether
     * the query <i>will</i> or <i>will not</i> be cancelled. The actual cancellation
     * may take place after the method has returned and will do so by throwing a
     * <code>RepositoryException</code> on the thread where <code>Query.execute()</code>
     * is currently blocking.
     *
     * @return true if the query was executing and will be cancelled, or false if the query cannot not be cancelled
     * because it has either already finished executing, it has already been cancelled, or the implementation
     * does not support canceling queries.
     * @since 2.1
     */
public boolean cancel();
Comment by Peeter Piegaze [ 02/Apr/13 ]

Fixed





[JSR_333-53] SQL-2: clarify syntax of names and paths Created: 13/Sep/12  Updated: 25/Mar/13  Resolved: 25/Mar/13

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: thomasmueller2 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: checklater

 Description   

I would like to clear up the SQL-2 syntax for names and paths. From the JCR 2.0 spec:

6.7.4 Name
Name ::= '[' quotedName ']' | '[' simpleName ']' | simpleName
quotedName ::= /* A JCR Name */
simpleName ::= /* A JCR Name that is also a legal SQL identifier */

6.7.23 Path
Path ::= '[' quotedPath ']' | '[' simplePath ']' | simplePath
quotedPath ::= /* A JCR Path that contains non-SQL-legal characters */
simplePath ::= /* A JCR Name that contains only SQL-legal characters */

See the SQL:92 rules for <regular identifier> (in ISO/IEC 9075:1992 §5.2 <token> and <separator>).

I guess (not sure) that "quotedName" / "quotedPath" does not actually mean a name or path surrounded with single quotes, that means it wouldn't be the idea that the path /test/node can be surrounded in single quotes as in ['/test/node']. I guess the idea is to support bracketed identifiers that are delimited by brackets ([ ]) as in MS SQL Server:

http://msdn.microsoft.com/en-us/library/aa224033(v=sql.80).aspx
http://msdn.microsoft.com/en-us/library/ms176027(v=sql.90).aspx

That would mean spaces and special characters are preserved bracketed using [ ].

Not fully clear is how the characters [ and ] should be handled within bracketed identifiers. MS SQL Server requires doubling ] (so that [Employee]]] is the quoted version of Employee] ). That would mean a path test[1]/node would result in [test[1]]/node] (where [ is not doubled, only ]).

See also https://issues.apache.org/jira/browse/OAK-295



 Comments   
Comment by rhauch [ 13/Sep/12 ]

I agree that this is not clear. My understanding also matches Thomas' guess that "quotedName" does not actually mean a name surrounded by (single- or double-quotes), and the "quotedName" term might just as easily be renamed (e.g., to "complexName" or something similar) to fix the first part of this issue.

The second part is how to escape quoting characters within quoted names and paths. One option not mentioned above is to support using square brackets OR single quotes OR double quotes for quoting characters. This addresses a couple of problems:

1) If the name or path contains a quoting character (e.g., ']'), then one can simply choose to quote the name/path in the query using a different quoting character. IMO, such queries are far more readable than having to escape quoting characters. For example:

SELECT * FROM "Employee]"

is more readable (IMO) than:

SELECT * FROM [Employee]]]

Though this will likely handle most situations, it is technically possible for a name to contain all quoting characters. In this case, we would need an escaping mechanism. But isn't it more common in other languages/grammars to escape with a forward slash (e.g., "Employee\"") than repeated quote characters? (It certainly is far easier to parse.)

2) If the grammar were to allow quoting names and paths using single- or double-quotes (in addition to square brackets), then the JCR-SQL2 queries start looking more like SQL-92/99 queries, where double-quoted identifiers is far more common (although the SLQ-99 grammar does allow other quoting characters). Being similar to SQL-99 isn't a benefit in and of itself, but it does offer an advantage for JCR repository implementations that provide a JDBC driver implementation for use by JDBC clients – more JDBC clients support single- or double-quoted characters more naturally than other quoting characters, like square brackets.

Comment by thomasmueller2 [ 13/Sep/12 ]

> SELECT * FROM "Employee]"

While this is valid ANSI-SQL, as far as I understand it is not valid JCR SQL-2 syntax due to
6.7.34 Literal
Literal ::= CastLiteral | UncastLiteral
CastLiteral ::= 'CAST(' UncastLiteral ' AS ' PropertyType ')'
UncastLiteral ::= UnquotedLiteral | ''' UnquotedLiteral ''' | '“' UnquotedLiteral '“'
That means within JCR 2.0, double quotes can be used to quote literals (like in Javascript).

> But isn't it more common in other languages/grammars to escape with a forward slash ... than repeated quote characters?

In C style languages yes, but not in ANSI SQL. Well there are a few databases that do or did support backslash escaping, but ANSI SQL is clear about this.

> (It certainly is far easier to parse.)

I actually found it easier to parse two consecutive quotes. Also, I found two consecutive quotes easier to embed in Java:

String query = "select * from [nt:base] where [name] = 'Joe''s Bar'";

versus

String query = "select * from [nt:base] where [name] = 'Joe\\'s Bar'";

Please note backslash is used as the escape character to escape "%" and "_" in like statements, as in

    where [priceLabel] like '%\%%'

(matches anything that contains a % character)

Double quoted identifier versus using square brackets: Double quoted identifiers are ANSI SQL, and most if not all databases support them. I believe square brackets is Microsoft syntax (MS SQL Server, Access). Plus some other databases, for example SQLite. I think it's OK to use them in our context, specially because double quotes is very problematic for C style languages:

String query = "select * from \"nt:base\" where \"name\" = 'Joe''s Bar'";
Comment by rhauch [ 13/Sep/12 ]

> SELECT * FROM "Employee]"

While this is valid ANSI-SQL, as far as I understand it is not valid JCR SQL-2 syntax due to
6.7.34 Literal
Literal ::= CastLiteral | UncastLiteral
CastLiteral ::= 'CAST(' UncastLiteral ' AS ' PropertyType ')'
UncastLiteral ::= UnquotedLiteral | ''' UnquotedLiteral ''' | '“' UnquotedLiteral '“'
That means within JCR 2.0, double quotes can be used to quote literals (like in Javascript).

I agree that it is not valid JCR-SQL2 as defined by JSR-283. However, the grammar for JSR-333 could easily be changed to support this (in addition to the existing square bracket quoting characters). It is true that in JSR-283 double- or single-quoted strings are indeed literals, but if additional quoting characters were added in JSR-333 then parsing is merely a matter of context. Plus, implementing support for additional quoted characters is extremely simple to do, and it doesn't impact any other part of the grammar or processing. (I guess it does depend upon a parser's implementation.)

Comment by thomasmueller2 [ 14/Sep/12 ]

> the grammar for JSR-333 could easily be changed to support this

Do you mean add a new query language, for example SQL-3, in JSR-333? For SQL-2, the disadvantage is that it would break backward compatibility, so that some SQL-2 queries wouldn't work. What would be bad (I'm not sure it's possible) if existing queries would be interpreted in a different way (the queries still working, but producing a different result). But I wouldn't mind if we discontinue support for double quoted string literals, for SQL-2, in JSR-333 as a first step.

Comment by rhauch [ 14/Sep/12 ]

> the grammar for JSR-333 could easily be changed to support this

Do you mean add a new query language, for example SQL-3, in JSR-333? For SQL-2, the disadvantage is that it would break backward compatibility, so that some SQL-2 queries wouldn't work. What would be bad (I'm not sure it's possible) if existing queries would be interpreted in a different way (the queries still working, but producing a different result). But I wouldn't mind if we discontinue support for double quoted string literals, for SQL-2, in JSR-333 as a first step.

No, I actually mean that the JCR-SQL2 grammar could be changed in JSR-333, so long as it is backward compatible with the JCR-SQL2 grammar in JSR-283. Adding more quote character options would absolutely be backward compatible, because queries that used square brackets to quote identifiers would still be valid. With the change, queries that used single- or double-quote characters to quote identifiers would also be valid in JSR-333.

Note that I'm not proposing to remove support for double quoted string literals. I'm merely proposing that JSR-333 could allow identifiers to be quoted using square brackets (as with JSR-283), single quotes, or double quotes.

Comment by rhauch [ 14/Sep/12 ]

BTW, I strongly advocate that all JCR-SQL2 queries considered valid per JSR-283 should remain valid in JSR-333.

Comment by thomasmueller2 [ 14/Sep/12 ]

I'm still not sure if I understand what you mean. Do you propose that the term "abc" can stand for a quoted identifier, or a string literal, depending on the parse context? The same for the term 'abc'? I know it's technically possible currently as the SQL-2 grammar never allows either a literal or a name at the same place - according to http://www.h2database.com/jcr/grammar.html - but it would be strange if the condition 'x' = 'y' would actually mean "compare property x with literal 'y'". It would disallow supporting conditions of the form "literal = property" and other relatively simple constructs (typecasting of properties) in future versions of the JCR spec. That would be strange in my view.

Comment by rhauch [ 14/Sep/12 ]

Obviously identifiers don't need to be quoted if all characters are "legal SQL characters".

Do you propose that the term "abc" can stand for a quoted identifier, or a string literal, depending on the parse context? The same for the term 'abc'? I know it's technically possible currently as the SQL-2 grammar never allows either a literal or a name at the same place - according to http://www.h2database.com/jcr/grammar.html - but it would be strange if the condition 'x' = 'y' would actually mean "compare property x with literal 'y'". It would disallow supporting conditions of the form "literal = property" and other relatively simple constructs (typecasting of properties) in future versions of the JCR spec. That would be strange in my view.

Yes, that is exactly what I mean, and this form is exactly what one would use with Oracle and MySQL. The Oracle 11g documentation states:

A quoted identifier begins and ends with double quotation marks ("). If you name a schema object using a quoted identifier, then you must use the double quotation marks whenever you refer to that object.

So in Oracle, this is not only valid but the use of double quotes around the column identifier is required:

SELECT * FROM someTable WHERE "column.with.punctuation" = "some literal value"

MySQL 5.x documentation states:

The identifier quote character is the backtick (“`”):

mysql> SELECT * FROM `select` WHERE `select`.id > 100;

If the ANSI_QUOTES SQL mode is enabled, it is also permissible to quote identifiers within double quotation marks:

mysql> CREATE TABLE "test" (col INT);
ERROR 1064: You have an error in your SQL syntax...
mysql> SET sql_mode='ANSI_QUOTES';
mysql> CREATE TABLE "test" (col INT);
Query OK, 0 rows affected (0.00 sec)

Note that MySQL uses a backtick for quoting, but setting the mode to ANSI_QUOTES switches the quote character to the double-quote.

Comment by thomasmueller2 [ 14/Sep/12 ]

SELECT * FROM someTable WHERE "column.with.punctuation" = "some literal value"

This query will fail in all relational databases I know unless there is a column called "some literal value". You can try it yourself in http://sqlfiddle.com/

In ANSI SQL, string literals need to be surrounded with single quotes.

Comment by thomasmueller2 [ 14/Sep/12 ]

I know that in relational databases, the double quote is used to quote identifiers. I also know about the backtick in MySQL and so on.

It's just that in the JCR 2.0 specification, the double quote is clearly defined to quote literals (for whatever reason). Changing that will break backward compatibility.

Comment by rhauch [ 02/Oct/12 ]

I do agree that JSR-283 does currently uses double quotes only in the grammar rules for literals, but I don't see anything in -283 that states that double quotes will be used in JCR-SQL2 only for this purpose. If JSR-333 were to add rules or change the existing grammar rules so that all JCR-SQL2 queries that were valid in JSR-283 were also valid in JSR-333, then an implementation could make be backward compatible.

Whether a particular implementation's parser is able to easily support using double quotes for things other than literals is generally not our concern. (It would be if we think it's not possible for any implementation to parse this. But it is absolutely possible for a parser to accept double quotes around identifiers and literals. For example, ModeShape has supported this for several years.)

Comment by thomasmueller2 [ 15/Oct/12 ]

I think we have our wires crossed...

I'm worried that supporting double quotes both to quote identifiers and to quote literals would lead us to a dead end. Technically, it might be possible to support it in the parser, given the current limitations of JCR-SQL2 (literals always need to be on the right hand side of a condition, identifiers always on the left hand side, and it is not allowed to use literals on both sides or identifiers on both sides except for joins where literals are not currently allowed).

Yes, technically, it should be possible to support it, at least in a hand written parser. But I'm not sure if it's possible to support it in a parser generated by ANTLR or JavaCC or when using another parser generator.

But in any case, for a user that is not very familiar with the JCR-SQL2 rules, it would not be clear. As an example, the following query could have multiple meanings:

SELECT * FROM [nt:base] WHERE "x" = "y"

It could mean:

  • where the property x contains the string value y
  • where the property y contains the string value x
  • where the property x is the same as the property y
  • where the string value x is equal to the string value y (always false)

It would not be clear for the user (the person reading / writing the query).

And it would not be clear to the parser if we ever want to extend JCR-SQL2 in the direction of ANSI SQL, that is if we also want to support literals in join conditions, literals on the left hand side of a condition, and so on. So basically, supporting double quotes for both literals and identifiers would prevent us from ever supporting more advanced syntax.

Comment by Peeter Piegaze [ 20/Feb/13 ]

@Thomas: How would you fix/clarify the BNF?

Comment by thomasmueller2 [ 20/Feb/13 ]

As for identifiers quoted with [ and ], I would follow the MS SQL Server style, so that to escape a ] characters, doubling is required: [abc:[def]]] would refer to the node type "abc:[def]". (I'm not sure if such node types are allowed, this example is just to explain how to escape / de-escape).

As for changes to the spec, I would write the following. Also, it might make sense to show an example in each case, for illustration:

6.7.4 Name
Name ::= '[' quotedName ']' | simpleName
quotedName ::= /* A JCR Name, where the ']' character is escaped as ']]'. */
simpleName ::= /* A JCR Name that is also a legal SQL identifier */

Example names are: test, [test], [nt:base], [abc.[def]]]. The last example is the quoted form of the name "abc.[def]".

6.7.23 Path
Path ::= '[' quotedPath ']' | simplePath
quotedPath ::= /* A JCR Path that may contain non-SQL-legal characters, and the ']' character is escaped as ']]' */
simplePath ::= /* A JCR Name that contains only SQL-legal characters */

Example paths are: blog, [blog/Hello World], [blog/[1]]]. The last example is the quoted form of the path "blog/[1]".

Regards,
Thomas

Comment by Peeter Piegaze [ 25/Mar/13 ]

Ok, I will change the grammar as suggested. But, just for the sake of clarity, I think I understand how this trouble came about:

1. The terminology "quotedName" etc is confusing, I grant you that. It was not meant to indicate a string already in quotes, but rather a string that needs quotes (or some type of delimiters, due to it containing otherwise invalid chars). However, the pattern of using "quoted" in this way in the spec is widespread and I don't hink it is worth fixing at this point.

2. The delimiters '[' and ']' were chosen precisely because they are not valid characters in a JCR Name. Therefore there should be no reason to worry about escaping them (but see next point).

3. When we selected [ and ] as delimiters we made a mistake! because at the same time (JCR 2.0) we also introduced the distinction between expanded and qualified forms of JCR names. Pre-2.0 it was true that [ and ] were invalid within a JCR Name (what we now call qualified form, with the prefix, e.g., jcr:content etc.)

However, as of 2.0 we allowed JCR Names to be written in expanded form which includes an explicit URI, like this

{http://foo.com/bar}

blah. The trouble is that now it is possible to have a [ or ] in a JCR name because those characters are valid within a URI.

So, it turns out you are right and I will fix the grammar. Just thought you'd like to know what the background was.

Comment by Peeter Piegaze [ 25/Mar/13 ]

Fixed.

Comment by thomasmueller2 [ 25/Mar/13 ]

> The terminology "quotedName" etc is confusing

I think there is no need to change the term.

The problem really should have been found when implementing the parser in Jackrabbit, and I did that, and I didn't see the problem back then. So really it's my mistake... But it can only be fixed in the spec, and it's good that this can be done now.

Thanks!





[JSR_333-60] i18n Created: 24/Oct/12  Updated: 22/Mar/13  Resolved: 22/Mar/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I know this is a big one and which afaik so far was intentionally left out of the spec. Right now JCR does not cover i18n at all. There are obviously different strategies, like namespacing the property names for different locales, or storing the translateable content pieces in child nodes .. or referencing nodes with the translations etc. Another topic are fallback rules, ie. it might make sense to show content in english if there is no text in german for the given node/property.

For PHPCR we have actually created a solution that abstracts this inside PHPCR ODM (a hibernate like layer on top of PHPCR):
http://docs.doctrine-project.org/projects/doctrine-phpcr-odm/en/latest/reference/multilang.html

But its obviously not so trivial to then deal with this in the context of search:
http://doctrine-project.org/jira/browse/PHPCR-84

At any rate the question is if i18n might be a topic that eventually could be covered in the core spec?



 Comments   
Comment by Peeter Piegaze [ 25/Oct/12 ]

Yes i18n is definitely something we are interested in. In fact, we had a container issue (JSR-333-11) which I closed due to lack of interest. But since there is now interest we can continue the discussion. I wil leave the old issue closed and use this one.

Could you describe the approach of PHPCR in more detail? What aspects of the API would be changed to accomodate i18n?

Comment by lsmith77 [ 25/Oct/12 ]

Just to clarify, its not something we did on the PHPCR level.
Its just something we did on the optional data mapper PHPCR ODM.

Basically you can define which properties are translatable and what strategy to use for storing the translations.

So lets say you want to store a class instance with the properties "title", "body" and "date". The date will be the same for all languages, but the title and body need to be translated. If you use the "attribute" strategy for the locale "en" what will happen is that the data is persisted as:

  • property: phpcr_locale:en-title
  • property: phpcr_locale:en-body
  • property: date

When using the "child" strategy it would be stored like so:

  • child phpcr_locale:en
  • title
  • body
  • date

When fetching the content the user either defines the locale they want, or a session default locale is used. If the content in the requested locale doesnt exist, an optional fallback chain can be triggered which again is configured on the session.

This works pretty well in that most frontend code can get away with no i18n specific code. Only in the authoring you may need to deal with i18n by presenting multiple forms for each locale and ensuring that the content provided is persisted for the correct locale.

Where it however starts to fall flat is when doing searches. At that point it becomes important what strategy is used.

Speaking of the strategies, each approach obviously has advantages:

  • attribute strategy keeps are node structure "as is", however it means that if there are a lot of different translations reading a node can add a lot of overhead
  • child strategy scales nicely with more translations, however querying the child nodes because more cumbersome and reading the child node (especially for fallbacks) adds overhead (especially in the client-server setup).

Another strategy we have not implemented yet would be to use references to interlink the different locale variations.

Comment by lsmith77 [ 25/Oct/12 ]

Now what I would prefer instead would be to essentially just be able to define the locale for the session (with an optional locale parameter when fetching a node to override the session default). Same when storing a node I would like to be able to provide a locale. There would need to be some way to change the locale of the node in memory. Similar to the "depthHint" we might then also need to define how aggressively all the different locale variations should be loaded. I will try to cook up some pseudo API examples over the weekend. But in many ways the following link describing how things work in the PHPCR ODM would be what I would like to see for the node API:
http://docs.doctrine-project.org/projects/doctrine-phpcr-odm/en/latest/reference/multilang.html#full-example

When querying I would then want to be able to specify the locales to consider and each node would only be returned once, regardless of the number of locales matched.

Comment by Peeter Piegaze [ 20/Feb/13 ]

One of the reasons we left i18n out of the spec is because we at Day/Adobe have always pushed the locale division to the top of the content tree:

/content/mysite/en/foo
/content/mysite/en/bar
/content/mysite/fr/foo
/content/mysite/fr/bar

and therefore management of i18n becomes much more an app-level concern (i.e., app on top of JCR repo platform).

In our experience having the translations down it the fine-grained content led to more trouble than it was worth and also, we found that "falling back to English" led to a pretty crappy experience for users , at least in the types websites our customer deploy.

For these reasons this has never been something we see as repo-level.

Now, there may well be contexts in which it does make sense to do things this way, but even then, would this not be better handled as a matter app best practices or something?

Comment by Peeter Piegaze [ 22/Mar/13 ]

Resolving as wontfix





[JSR_333-45] clarify uniqueness requirement on lock tokens Created: 17/Jan/12  Updated: 22/Mar/13  Resolved: 22/Mar/13

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: reschke Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: checklater

 Description   

We should clarify the uniqueness requirement for lock tokens. Right now the spec says:

"A lock token is a string that uniquely identifies a particular lock and acts as a key granting lock ownership to any session that hold the token." <http://www.day.com/specs/jcr/2.0/17_Locking.html#17.5%20Lock%20Token>

So locking a node, unlocking it, then locking again creates two locks; are those "different" locks, thus require different lock tokens? I believe so, but the RI currently returns the same lock token (based on the node's internal id).

See <https://issues.apache.org/jira/browse/JCR-3208> for discussion around the Jackrabbit issue.



 Comments   
Comment by Peeter Piegaze [ 06/Mar/12 ]

Just took a look at the related Jackrabbit issue. It seems that requiring a unique token for each "act of locking" leads to a reprecussion on the LockEventListener interface (would require adding a locktoken param).

So, is it best to instead explicitly relax the spec requirement to make it line up with the current JR behavior? Or is there a real need to stick to the original (stronger) intent of the spec?

Comment by reschke [ 06/Mar/12 ]

I think the stronger intent is correct; you don't want a client to unlock a node that was unlocked and then locked again in the meantime.

Comment by Peeter Piegaze [ 20/Feb/13 ]

Ok, I will add the language clarifying the stronger intent

Comment by Peeter Piegaze [ 22/Mar/13 ]

Added the following clarification to spec 16.5 Lock Token

The lock tocken is unique to each discrete locking event, in the sense that if a node is locked and unlocked multiple times, the Lock objects returned each time the lock is placed, must contain distinct, unique lock tokens.





[JSR_333-64] API inconsistencies Created: 03/Dec/12  Updated: 22/Mar/13  Resolved: 22/Mar/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: dbu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

during JSR_333-59 i stumbled over a couple of issues:

Session getNodesByIdentifier, getNodesByPath and getPropertiesByPath - should those not be plural twice? as in getNodesByIdentifiers and ...ByPaths with "s" at the end?

And what happens if one of the paths identifies the wrong item type? leave that field out, like not found paths?

some @since annotations are not consistent. "2.1" vs "JCR 2.1"

a few files contain tabulator instead of spaces

in the doc of Session.getNodes with depthHint, there is one place a literal > instead of >

EventFilter

  • doc comment is talking about returning Event*Listener* object in fluent interface.
  • nodeTypes or nodeTypeName? there is still some occurences of nodeTypeName

ObservationManager

  • .addEventListener garbled comment in second paragraph (will be \n will be)
  • .createEventFilter is missing @since annotation

AccessControlManager:

  • getSupportedPrivileges garbled comment (the privilege of being \n able administer the node type registry) => being able to administer.
  • getPrivileges second paragraph is not updated to new concept of allowing null path (it still says "Returns the privileges the session has for absolute path absPath, which \n must be an existing node.")


 Comments   
Comment by Peeter Piegaze [ 20/Feb/13 ]

Regarding the getNodesByIdentifier vs getNodesByIdentifiers etc.:

Though logically it might seem to make sense to pluralize the "Identifier*s*" I can tell you that it actually sounds better in English the way it is.

It is more natural in English to say "Sort the apples by size" rather than "Sort the apples by sizes".

Regarding the typos and garbled text I'll check it out and fix it.

Comment by dbu [ 20/Feb/13 ]

ah i see. i was thinking to technical. when thinking in language, it makes sense to leave as is, agreed.

Comment by Peeter Piegaze [ 22/Mar/13 ]

fixed as described below:

during JSR_333-59 i stumbled over a couple of issues:

Session getNodesByIdentifier, getNodesByPath and getPropertiesByPath - should those not be plural twice? as in getNodesByIdentifiers and ...ByPaths with "s" at the end?

  • Leave as is, ok language-wise

And what happens if one of the paths identifies the wrong item type? leave that field out, like not found paths?

  • ids that dont refer to accessible nodes and paths that dont refer to accesible items of the correct type are ignored.. javadoc clarified

some @since annotations are not consistent. "2.1" vs "JCR 2.1"

  • Found two cases: fixed.

a few files contain tabulator instead of spaces

  • found all tabs: replaced with spaces or emoved as necesary, found all trailing spaces, removed

in the doc of Session.getNodes with depthHint, there is one place a literal > instead of >

  • fixed

EventFilter
doc comment is talking about returning Event*Listener* object in fluent interface.
nodeTypes or nodeTypeName? there is still some occurences of nodeTypeName

  • fixed

ObservationManager
.addEventListener garbled comment in second paragraph (will be \n will be)
.createEventFilter is missing @since annotation

  • fixed

AccessControlManager:
getSupportedPrivileges garbled comment (the privilege of being \n able administer the node type registry) => being able to administer.
getPrivileges second paragraph is not updated to new concept of allowing null path (it still says "Returns the privileges the session has for absolute path absPath, which \n must be an existing node.")

  • fixed




[JSR_333-66] make it possible to filter not only by property name, but also by node type Created: 08/Feb/13  Updated: 22/Mar/13  Resolved: 22/Mar/13

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Node#getNodes() currently accepts a filter for the node names. it would be useful to optionally also allow filtering by node type.

btw: the same should be added to Node#getNodeNames() too for consistency. see the note I wrote in JSR_333-57



 Comments   
Comment by Peeter Piegaze [ 20/Feb/13 ]

Anyone object to this? I assume it would be no more difficult to implement than filter by name, and it seems useful.

Comment by Peeter Piegaze [ 06/Mar/13 ]

So, would the proposal be to add something like:

Node.getNodesByType(String[] typeGlobs)

I assume the following semantics:

On N.getNodesByType(G) where N is a node and G is an array of globbing strings

  • For each immediate child node C of N that is accessible via the current session:
    • For each node type T where C.isNodeType(T) == true
      • For each string t where t is first the expanded form and then the qualified form of T (e.g. t takes on value "nt:file" and then " {http://www.jcp.org/jcr/nt/1.0}

        :file")

        • For each globbing string g in G
          • If g matches t then C is returned in the NodeIterator

Is that what you had in mind?

Comment by dbu [ 22/Mar/13 ]

i think it would make sense to have a getNodesByTypeAndName as well. (in phpcr we simply make the type argument optional, guess java can't do that)

i am not sure if this has such a small impact. with jackrabbit davex for example, the node knows its children names so can filter without loading the nodes. for the types, it first needs to load the nodes. but this should not prevent us from adding this if we think it is useful - davex is implementation specific and we could optimize it for example by providing the child node types along with the child names when reading a node...

Comment by Peeter Piegaze [ 22/Mar/13 ]

Ok here is a new proposal
As of 2.1 this part of the Node interface will look like this:
(i'll cover everything, just to keep it clear).

Node
#getNodes()  // Keep
#getNodes(String namePattern)  // Deprecate
#getNodes(String[] nameGlobs)  // Keep
#getNodes(String[] nameGlobs, String[] typeGlobs)  // New in 2.1
#getNodesByType(String[] typeGlobs)  // Revert recent addition of this method in 2.1
#getNodeNames()  // New in 2.1
#getNodeNames(String[] nameGlobs) // New in 2.1
#getNodeNames(String[] nameGlobs, String[] typeGlobs)  // New in 2.1
#getProperties()  // Keep
#getProperties(String namePattern) // Deprecate
#getProperties(String[] nameGlobs) // Keep
Comment by Peeter Piegaze [ 22/Mar/13 ]

fixed as described above.





[JSR_333-67] filter names on Node.getNodeNames Created: 28/Feb/13  Updated: 05/Mar/13  Resolved: 05/Mar/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: dbu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

as this might be lost in the comment of JSR_333-57 : can we add the filter parameter to Node.getNodeNames too? it would make sense and should be cheap to implement, all the logic will be there from Node.getNodes anyways.



 Comments   
Comment by Peeter Piegaze [ 01/Mar/13 ]

I agree. I will make the required changes.

Comment by dbu [ 02/Mar/13 ]

just created the pull request on PHPCR https://github.com/phpcr/phpcr/pull/57

Comment by Peeter Piegaze [ 05/Mar/13 ]

I have added the following new method sigs:

StringIterator Node.getNodeNames(String namePattern)

StringIterator Node.getNodeNames(String[] nameGlobs)

Comment by dbu [ 05/Mar/13 ]

cool, thanks. in php its all in one method, like Node::getNodes()





[JSR_333-61] add capability for implementations that support "copy on write" workspace cloning Created: 07/Nov/12  Updated: 01/Mar/13  Resolved: 01/Mar/13

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

the idea is that an implementation can communicate via the capabilities if it supports "cheap" workspace cloning via copy on write. this means that cloning a workspace would dulicate zero data. only changes in the cloned workspace would need to be persisted. this can be useful to enable more liberally using separate workspaces to stage different related changes, even going so far as to give every content author a workspace of their own.

one question here would be how changes in the cloned repository would be dealt with. either these would then automatically shine through to cloned repositories. this would in many ways be a quite appealing feature (see http://www.slideshare.net/kfish/typo3-cr-in-phoenix), but it might make sense to different here between implementations that shine through or that ensure that the cloned repositories then still see the version of the cloned workspace from the point in time when they were cloned.

alternatively one could also consider introducing a separate method call for "shine through" workspace cloning.



 Comments   
Comment by stefan_guggisberg [ 07/Nov/12 ]

FWIW, comments by an old fart

in JSR-170 we once supported the concept of stable (opaque) and dynamic (transparent) workspaces.

every dynamic workspace had one stable workspace that served as its base, while a given stable workspace could serve as the base for zero or more dynamic workspaces. changes to a stable workspace would immediately be visible within all dynamic workspaces based on that stable workspace, unless they were over-ridden by changes in a dynamic workspace.

since for API consumers there's no semantic distinction between stable and dynamic workspaces the JSR-170 expert group considered it an implementation choice and decided to de-emphasize the distinction in the spec (as of draft v0.11, march-04).

IMO re-introducing the distinction of stable vs dynamic workspaces is not worth the effort since it significantly adds complexity to spec without providing real value to API consumers.

Comment by lsmith77 [ 07/Nov/12 ]

i think there is quite an important difference for API consumers if they can "stage" all their changes in a workspace or if they somehow themselves need to track what changes are related and ensure that they do not overlap with changes that someone else is preparing while still seeing changes for non overlapping changes.

so i agree that it brings a lot of complexity, which is why i would be happy if we just add a capability that can be checked against to cleanly determine what approach the underlying implementation has chosen.

Comment by stefan_guggisberg [ 07/Nov/12 ]

so i agree that it brings a lot of complexity, which is why i would be happy if we just add a capability that can be checked against to cleanly determine what approach the underlying implementation has chosen.

how would simply adding a new capability repository descriptor help here? without clearly specifying the semantics of dynamic workspaces (e.g. how conflicts should be handled) i fail to see the benefit of introducing such a descriptor.

Comment by lsmith77 [ 07/Nov/12 ]

the capability would be just for "copy on write" workspaces, not for stable vs. dynamic.

Comment by stefan_guggisberg [ 07/Nov/12 ]

the capability would be just for "copy on write" workspaces, not for stable vs. dynamic.

IIUC dynamic and copy on write workspaces are conceptually identical.

Comment by rhauch [ 07/Nov/12 ]

Is it true that an implementation would be required to support one versus the other (e.g., "stable" vs. "dynamic")? Might some workspaces be "stable" while others are "dynamic", and if so then how would that be described using a single repository-level descriptor?

Plus, what would a JCR client do with this information? IMO, this seems like an implementation detail (and possibly configuration-specific, too) that needs not be exposed to the clients.

Comment by lsmith77 [ 07/Nov/12 ]

well my assumption is that copy on write doesnt imply dynamic. ie. when using copy on write it would be the implementors job to prevent changes in the source workspace to propagate to the cloned repository.

now as to why this is useful, my idea was to then allow the CMS to choose a different strategy for content staging based on this information. ie if i know the repository is copy on write, it might simple automatically clone a workspace for the user, while if it doesnt, it might need to provide some alternative mechanism to track related changes. however one could make this of course also an explicit configuration of the CMS itself.

Comment by Peeter Piegaze [ 19/Nov/12 ]

I doubt that this type of capability information would in reality be that useful.

It just seems very unlikely that someone writing an app on top of JCR that would include two different implementations of a complex higher-level feature and then switch between those implementations based on a programmatic check on this capability.

-1 on this

Comment by Peeter Piegaze [ 20/Feb/13 ]

I recommend we resolve this as wontfix

Comment by Peeter Piegaze [ 01/Mar/13 ]

wontfix





[JSR_333-8] Protocol and SPI bindings Created: 01/Sep/10  Updated: 01/Mar/13  Resolved: 01/Mar/13

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 8
Tags: checklater

 Description   

One of the goals of JSR 333 is to specify protocol bindings to JCR and possibly an SPI. I am opening this
issue as a container for suggestions on how to do that. Individual improvements that we agree upon can
then get their own issues later.



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Enhancement

Comment by Peeter Piegaze [ 13/Sep/12 ]

Ok JSR-333 is back from deep space hibernation.

So, does anyone have a strongly held opinion on adding protocol and or SPI to the spec?

Comment by rhauch [ 13/Sep/12 ]

This is to define a protocol for use in communications between a client and (remote) server? What would the SPI be used for?

Comment by Peeter Piegaze [ 02/Oct/12 ]

The SPI would be a server side to server-side API presented in a non-OO fashion as a flat list of methods. Maybe something like this http://jackrabbit.apache.org/api/2.4/org/apache/jackrabbit/jcr2spi/operation/package-summary.html

Comment by Peeter Piegaze [ 19/Feb/13 ]

Unless someone objects, I am inclined to resolve this as wontfix.

Comment by Peeter Piegaze [ 01/Mar/13 ]

wontfix





[JSR_333-57] give access to the list of child node names Created: 16/Oct/12  Updated: 08/Feb/13  Resolved: 23/Oct/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: lsmith77 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

instead of having to iterate of the nodes, it would be useful to simply get the list of child node names. this can for example be used to add a way to cycle through all the child nodes of a parent.

imagine a node /news with /news/first /news/second /news/third /news/fourth
when the user is presented the UI for /news/second it may be useful to allow them to have links pointing to /news/first and /news/third
currently this requires fetching the parent, then getting an iterator with the children and then iterating to find the proper nodes.



 Comments   
Comment by stefan_guggisberg [ 17/Oct/12 ]

proposal:

add

StringIterator Node#getNodeNames() throws RepositoryException

Comment by rhauch [ 17/Oct/12 ]

What does StringIterator look like? Is it a RangeIterator, or could it just be a Iterator<String>?

An advantage of adding this method is that it may (depending upon the implementation) prevent the loading of the child nodes when the client only needs the child names.

Comment by stefan_guggisberg [ 17/Oct/12 ]

What does StringIterator look like? Is it a RangeIterator, or could it just be a Iterator<String>?

good point! i (wrongly) assumed that there's already a javax.jcr.StringIterator.

it should be a RangeIterator (i.e. same semantics as NodeIterator).

Comment by Peeter Piegaze [ 23/Oct/12 ]

Node.getNodeNames and StringIterator added as suggested.

Comment by lsmith77 [ 26/Jan/13 ]

i have begun leveraging this new method inside a PHPCR project and found that it would be useful to also support a filter parameter like we do in getNodes. what do you think?

Comment by lsmith77 [ 08/Feb/13 ]

see also JSR_333-66





[JSR_333-62] support for hash maps Created: 16/Nov/12  Updated: 19/Nov/12  Resolved: 19/Nov/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Interpreted languages like PHP make considerable use of hash maps:
$php = array('foo' => 'bar', 'ding' => 'dong');

It would be useful to be able to persist such data as a multivalued property. Currently its only possible to persist ordered lists like:
$php = array(0 => 'bar', 1 => 'dong');

As a result when someone currently wants to persist the above hash map its necessary to split keys and values:
$keys = array(0 => 'foo', 1 => 'ding');
$values = array(0 => 'bar', 1 => 'dong');

Alternatively it would be possible to use subnodes for this, ie. storing a child node 'foo' with a property 'value' set to 'bar' etc, which imho is neither practical (rather than just calling setProperty() it would not be necessary to build lots of Node instances) nor efficient (a node has lots of additional features over a plain property like versioning etc) nor semantically sensible (if there wouldnt be a difference between properties and nodes there would be no need to have ever introduced multi valued properties to begin with).

Related to this see: http://mail-archives.apache.org/mod_mbox/jackrabbit-oak-dev/201211.mbox/%3c8035DC13-DA1D-4A9F-961B-C3BD7A0B3614@pooteeweet.org%3e



 Comments   
Comment by rhauch [ 16/Nov/12 ]

I don't see how this could be retrofitted on top of the existing JCR API without a lot of extra work, considering that single-valued properties can only have a single literal value, and multi-valued properties are exposed as arrays (rather than an abstraction such as a "sequence of values"). Considering we can't really change those APIs (and I would argue against anyone wanting to do that as it would break backward compatibility), it doesn't appear that we can retrofit this feature into the current design.

Does it make more sense for your applications to store each entry in the map as a STRING value? e.g., "'foo'=>'bar'"

If not, then can envision two approaches that might solve this in a less-than-cludgy way:

1) Add a new type of property in addition to single-valued and multi-valued properties; perhaps a "key-valued" property that can be accessed like a map.
2) Introduce a new PAIR (or other name??) property type that can be stored in a multi-valued property but accessed by looking up values by key (which may also work for existing value types by using integer keys).

But there are lots of issues that would have to be resolved with either approach:

  • What are the changes/additions to the API?
  • How (if at all) do the behaviors of current methods (e.g., "Property.isMultiple()") change to accommodate this new property?
  • How would the CND format change?
  • What's the impact on existing applications if they access a property that is a map property? Does it degrade to an array, and if so of what values?

I'm not sure we can honestly evaluate the idea without having some concrete proposals that have already identified or worked through many of the issues.

Comment by lsmith77 [ 16/Nov/12 ]

I dont have a good proposal either here, with the current available tools the best approach is splitting the keys and values into separate properties. its not ideal but it works ok-ish and yes the upgrade path seems tricky indeed, so its likely something that doesnt fit into a 2.1 release.

Comment by aklimets [ 19/Nov/12 ]

-1

JCR doesn't need a new property type "map", as properties on the node already cover that, or child nodes, if the values in the map contain deep structures ("objects").

The mentioned issues are just a problem of mapping that to the language-specific data structures and can be fixed and handled there.

Comment by Peeter Piegaze [ 19/Nov/12 ]

I agree that this will not be something we can deal with in 2.1, so I am resolving this as wont fix.





[JSR_333-36] PHPCR comments doc needs some language cleanup Created: 15/Jun/11  Updated: 06/Nov/12  Resolved: 06/Nov/12

Status: Closed
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates JSR_333-59 synchronize PHPCR to JCR Resolved

 Description   

The comments in PHPCR code could use a bit of clean up just from an English POV



 Comments   
Comment by dbu [ 29/Aug/11 ]

agreed. if anybody is up to do that, please use the most recent development code as base, available at https://github.com/phpcr/phpcr . we did quite a bit of refactoring and re-layouting the doc, a diff against the svn version would not be really helpful.

Comment by Peeter Piegaze [ 06/Nov/12 ]

The language cleanup will be part of the Java-PHP sync review. Marking this as dup and resolving





[JSR_333-47] Add Item.revert method Created: 15/Feb/12  Updated: 06/Nov/12  Resolved: 25/Oct/12

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: milestone 1
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: mduerig Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: doublecheck

 Description   

When a save operation failed, sessions may end up in a stale state: that is in a state where transient changes can neither reverted nor persisted. Previously Item.refresh() had some of the semantics of a revert operation but also included update. With the deprecation of Item.refresh() I suggest to add an Item.revert() method which reverts an items and all of its children by throwing away all transient changes made to that item and its child items.



 Comments   
Comment by Peeter Piegaze [ 06/Mar/12 ]

@Stefan Guggisberg
@Angela Schreiber

Do either of you have an opinion on this?

Comment by stefan_guggisberg [ 06/Mar/12 ]

i guess partially reverting transient changes is a legitimate use case.

+1 for the adding Item.revert()

Comment by Peeter Piegaze [ 25/Oct/12 ]

Method added as suggested:

/**

  • This method discards
  • all pending changes currently recorded in this <code>Session</code> that
  • apply to this Item or any of its child nodes and properties and returns these items to reflect the current saved
  • state. Outside a transaction this state is simply the current state of
  • persistent storage. Within a transaction, this state will reflect
  • persistent storage as modified by changes that have been saved but not
  • yet committed.
    *
  • @throws InvalidItemStateException if this <code>Item</code> object
  • represents a workspace item that has been removed (either by this session
  • or another).
  • @throws RepositoryException if another error occurs.
  • @since JCR 2.1
    */
    public void revert() throws InvalidItemStateException, RepositoryException;
Comment by rhauch [ 25/Oct/12 ]

I'm confused as to why this method was added. JSR-333-42 deprecated "Item.refresh(boolean)" because it was not useful beyond what Session.refresh(boolean) does. So deprecating "Item.refresh" makes a lot of sense (and I also agree it was difficult to implement).

How is adding "Item.revert()" any less difficult to implement? What is use case where this new method would be useful and offer different behavior from "Session.refresh(false)"?





[JSR_333-35] Add Access Control to PHPCR Created: 10/Jun/11  Updated: 30/Oct/12  Resolved: 30/Oct/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: checklater

 Description   

When/if AC is added to Jackalope, it should be added to the spec



 Comments   
Comment by lsmith77 [ 16/Oct/12 ]

this ticket is currently hindered by the fact that the reference implementation of PHPCR uses Jackrabbit for storage via HTTP/Davex, which does not expose the ACL API via HTTP/Davex.

Comment by Peeter Piegaze [ 30/Oct/12 ]

From an API POV the interfaces are defined in PHPCR, so that is sufficient to close this.

Comment by dbu [ 30/Oct/12 ]

we did review the interfaces in spring and feel that they should be correct and implementable once we have a backend that can do it. so yes, think this is fine.





[JSR_333-34] Decide on Retention Created: 10/Jun/11  Updated: 30/Oct/12  Resolved: 30/Oct/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: checklater

 Description   

Retention is mentioned as a feature missing from PHPCR. It seems likely that this will not be added to PHPCR, however I have opened th issue just to track it



 Comments   
Comment by Peeter Piegaze [ 30/Oct/12 ]

Hold interfaces define in phpcr





[JSR_333-33] Add Observation to PHPCR Created: 10/Jun/11  Updated: 30/Oct/12  Resolved: 30/Oct/12

Status: Closed
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: checklater

 Description   

When Observation is finalized in Jackalope, it should be added to PHPCR



 Comments   
Comment by dbu [ 11/Aug/11 ]

the challenge with observation is that php usually is bootstrapped for each request. it is probably to unefficient to register events for each requests. some sort of pull mechanism for asynchronous observation might be easier to do.

for the jackalope implementation with jackrabbit over davex, do registered observations survive a jackrabbit restart? that is 1) do we loose not yet fetched events and 2) do we have to re-register observations or will the events be generated?

Comment by lsmith77 [ 16/Oct/12 ]

afaik journal support is now implemented, which is likely sufficient in absence of an application server

Comment by dbu [ 24/Oct/12 ]

the api interfaces are there, and journal polling is implemented in jackalope-jackrabbit (though jackrabbit davex always returns all events, but only up to 10k entries, so its basically unusable) but for the interfaces part it makes sense as is.





[JSR_333-32] Add Locking to PHPCR Created: 10/Jun/11  Updated: 30/Oct/12  Resolved: 30/Oct/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: checklater

 Description   

When Locking is finalized in Jackalope, it should be added to PHPCR



 Comments   
Comment by dbu [ 24/Oct/12 ]

this is defined here https://github.com/phpcr/phpcr/tree/master/src/PHPCR/Lock

Comment by Peeter Piegaze [ 30/Oct/12 ]

Since the interfaces are defined in PHPCR, we can close this issue





[JSR_333-58] fix typo "node.type.management.update.in.use.suported" Created: 23/Oct/12  Updated: 25/Oct/12  Resolved: 25/Oct/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

"suported" is a typo in the current version of the spec. guess it should be fixed, not sure what to do for backwards compatibility.

in PHPCR we have left the string as is, but fixed the typo in the ReferenceInterface class constant:

\PHPCR\RepositoryInterface\NODE_TYPE_MANAGEMENT_UPDATE_IN_USE_SUPPORTED = = "node.type.management.update.in.use.suported";



 Comments   
Comment by Peeter Piegaze [ 25/Oct/12 ]

Misspelled constant deprecated. Added new correctly spelled constant with correctly spelled string value.





[JSR_333-56] support am optional depth parameter for Session.getNode() Created: 16/Oct/12  Updated: 25/Oct/12  Resolved: 25/Oct/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

afaik Jackrabbit already supports this. this is essentially just a performance hint implementations can choose to use.
setting this parameter to an integer value > 0 hints to the implementation that nodes up to the specified depth of children should be fetched into memory.



 Comments   
Comment by stefan_guggisberg [ 17/Oct/12 ]

FWIW:

we once (back in the evolving JSR 170 specification) had a special signature
of Node.getNodes with a 'depthHint' parameter, similar to what you are
suggesting.

we got rid of it because this was considered a implementation detail.
while such a depthHint would probably not do great harm, it somehow
implies a client-server architecture which we do not want to enforce.
the spec does not make any assumption on the architecture of the
implementation.

BTW: Jackrabbit does not support overloaded getNode/getNodes signatures
providing depthHint parameters. you're probably referring to the Jackrabbit SPI
which is a low-level interface not meant to be consumed directly.

Comment by lsmith77 [ 17/Oct/12 ]

yeah .. actually my view of Jackrabbit is pretty much based on the Davex API
indeed its an implementation detail, but leveraging it shouldnt make my code implementation specific ..

Comment by Peeter Piegaze [ 23/Oct/12 ]

Actually, since "improved client/server awareness" is supposed to be one of the design-goals for JSR 333, we are admitting that a strict "no assumptions about impl architecture" approach was probably too extreme. So, I think this addition would fit in with the design goal and should be adopted. And as Stefan says, it will not do any harm.

Comment by Peeter Piegaze [ 23/Oct/12 ]

I suggest we add the following method to Session:

/**

  • Returns the node at absPath in the workspace and optionally caches the
  • subtree to depth <code>depthHint</code> in preparation for possible future
  • access requests by the client.
    *
  • The parameter <code>depthHint</code> indicates the depth of the subtree of
  • <code>absPath</code> the client wishes to retrieve at the same time.
  • <code>depthHint</code> <i>may</i> be used by implementations improve
  • the efficiency of access for nodes further down the tree. This may, for
  • example, be advantageous to client-server JCR implmentations, to reduce
  • roundtrips to the server. An implementation is free to ignore the
  • <code>depthHint</code> parameter.
    *
  • If the implemention does not ignored <code>depthHint</code> then:
  • a <code>depthHint<code> of <code>0</code> results in the the equivalent of
  • <code>getNode(String absPath)</code> and a <code>depthHint</code>
  • <= -1 results in the caching of the maximum
  • depth achievable by the implementation.
    *
  • @param absPath An absolute path.
  • @param depthHint An integer.
    *
  • @return the specified <code>Node</code>.
  • @throws PathNotFoundException If no accessible node is found at the
  • specified path.
  • @throws RepositoryException If another error occurs.
  • @since JCR 2.1
    */
    public Node getNode(String absPath, int depth) throws PathNotFoundException, RepositoryException;
Comment by lsmith77 [ 23/Oct/12 ]

just a minor typo in the method signature .. it should be "int depthHint"

Comment by stefan_guggisberg [ 23/Oct/12 ]

some typos:

The parameter <code>depthHint</code> indicates the depth of the subtree of rooted at

<code>depthHint</code> <i>may</i> be used by implementations to improve

If the implemention does not ignored ignore <code>depthHint</code> then:

a <code>depthHint<code> of <code>0</code> results in the the equivalent of

Comment by stefan_guggisberg [ 23/Oct/12 ]

IMO we need to be more specific about the semantics of depthHint.

i would assume the following semantics:

depthHint = 0: specified node (incl. its properties) only
depthHint = 1: specified node (incl. its properties) and its direct child nodes
[and so forth]

an application might want to do a shallow getNode call if it knows
that the specified node contains a very large number of direct child nodes,
i.e. getNode("/nodeWithManyChildren", 0).

the javadoc proposal however states that getNode("/some/path", 0)
and getNode("/some/path") are equivalent. this OTOH implies a
subtle change in the semantics of getNode(String absPath),
i.e. the implied depthHint is 0 => shallow. so far we didn't make
any statements about the depth of getNode(String absPath).

i suggest we change the semantics to:

depthHint = 0: specified node (incl. its properties) only
depthHint < 0: equivalent to getNode(String absPath), i.e. an implementation specific default will be assumed

Comment by Peeter Piegaze [ 25/Oct/12 ]

Added Session#getNode(String absPath, int depthHint) as follows:

/**

  • Returns the node at <code>absPath</code> and optionally caches the subtree rooted
  • at <code>absPath</code>to depth <code>depthHint</code> in preparation for possible
  • future access requests by the client.
  • <p>
  • The parameter <code>depthHint</code> <i>may</i> be used by an implementation to
  • improve the efficiency of access for nodes in the subtree rooted at
  • <code>absPath</code>. This may, for example, be advantageous to client-server
  • implementations by reducing round-trips to the server. An implementation is free
  • to ignore the <code>depthHint</code> parameter.
  • <p>
  • If the implementation does not ignore <code>depthHint</code> then the following
  • rules apply:
  • <p>
  • <code>depthHint</code> < <code>0</code>: Equivalent to
  • {@link Session#getNode(String absPath)}

    .

  • <p>
  • <code>depthHint</code> = <code>0</code>: The node at <code>absPath</code> and all
  • its properties are retrieved. No child nodes (nor any further descendants) are
  • retrieved. This is referred to as a <i>shallow</i> <code>getNode</code>.
  • <p>
  • <code>depthHint</code> > <code>0</code>: The node at <code>absPath</code> and all
  • its properties are retrieved as well as all descendant nodes (and their respective
  • properties) up to degree <code>depthHint</code>. A <code>depthHint</code> of
  • <code>1</code> retrieves the node at <code>absPath</code> and all its child nodes.
  • A <code>depthHint</code> of <code>2</code> retrieves the node at <code>absPath</code>,
  • all its child nodes and all <i>their</i> child nodes in turn. And so on.
  • <p>
  • An implementation is free to set a limit on the amount of data cached due to the
  • <code>depthHint</code> parameter. Thus, the implementation may fail to retrieve
  • to the full depth requested in cases where that depth is large and the data size
  • of the nodes and properties in the subtree is also large. In order to guarantee
  • a retrieval to the maximum depth possible, the client can set <code>depthHint</code>
  • to <code>java.lang.Integer.MAX_VALUE</code>.
    *
  • @param absPath An absolute path.
  • @param depthHint An integer.
  • @return the specified <code>Node</code>.
  • @throws PathNotFoundException If no accessible node is found at the specified path.
  • @throws RepositoryException If another error occurs.
  • @since JCR 2.1
    */
    public Node getNode(String absPath, int depthHint) throws PathNotFoundException, RepositoryException;




[JSR_333-23] Make Iterators Iterable Created: 16/Feb/11  Updated: 24/Oct/12  Resolved: 10/Oct/12

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: thomasmueller2 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, iterating (for example over child nodes) is tedious:

for (NodeIterator it = node.getNodes(); it.hasNext() {
Node child = it.nextNode();
// ...
}

If the NodeIterator would be an Iterable<Node>, then the code would look like:

for (Node child : node.getNodes()) {
// ...
}

Which would avoid errors, ease reading the code, and mean less typing.

I believe this could be achieved in a backward compatible way as follows:

interface IterableNodeIterator extends Iterable<Node>, NodeIterator {
}

class IterableNodeIteratorImpl implements IterableNodeIterator {
public Iterator<Node> iterator()

{ return new ...(); }

}

Possibly we could just extend the NodeIterator interface to extend Iterable<Node> (I'm not sure). Anyway, it means existing code would continue to work as is (because IterableNodeIterator extends NodeIterator). New code could use the new, simplified iterator.

The same goes for RangeIterator and all other sub-interfaces (AccessControlPolicyIterator, EventIterator, EventJournal, EventListenerIterator, NodeTypeIterator, PropertyIterator, RowIterator, VersionIterator).



 Comments   
Comment by rhauch [ 16/Feb/11 ]

I definitely agree with this issue. But I'd prefer making NodeIterator extend Iterable<Node> for three reasons:
1) doing this would prevent the introduction of additional interfaces; and
2) this has a minimal impact on the API (only changing the interfaces) and is the only way to reuse the existing 'getNodes()' method signatures; and
3) the implementation of NodeIterator.iterator() can just return itself, saving the instantiation of another intermediate object.

Comment by thomasmueller2 [ 16/Feb/11 ]

I would also prefer making NodeIterator extend Iterable<Node>, if this is possible in every case. However, I'm not completely sure if it is possible, that means I don't know if every method that currently returns a NodeIterator is able to return a Iterable<Node>. If it's possible, then I suggest to make NodeIterator extend Iterable<Node>.

If it is not possible in every case (if we find out one of the method can't possibly return Iterable<Node>), then we could still add the feature in those cases where it is possible, using the interface IterableNodeIterator. The return type of the methods would be changed from NodeIterator to IterableNodeIterator. This change is backward compatible, because existing applications that expect a NodeIterator will still get one (because IterableNodeIterator extends NodeIterator), and new code can use the enhanced for loop because IterableNodeIterator extends Iterable<Node>.

So, let's find out if we can make NodeIterator extend Iterable<Node>.

Comment by thomasmueller2 [ 16/Feb/11 ]

> the implementation of NodeIterator.iterator() can just return itself

It is possible to return 'this' in the first call to the iterator() method. However, if iterator() is called again, then a new object needs to be created, because the first iterator may still be in use.

Comment by Peeter Piegaze [ 04/May/11 ]

In what hypothetical cases would returning an Iterable<Node> be impossible?

Comment by thomasmueller2 [ 05/May/11 ]

> In what hypothetical cases would returning an Iterable<Node> be impossible?

If the returned result can only be scanned once for technical reasons. I don't know of such a case for Apache Jackrabbit, but there might be some cases for other implementations.

For example, the JDBC APIs Statement.getResultSet() will by default return a result set that can only be scanned once (for many databases). So if a JCR implementation uses the JDBC API underneath, returning a Iterable<Node> instead of a NodeIterator might require quite a big change.

But I think we should still implement this feature, even if it is potentially hard to implement.

Comment by Peeter Piegaze [ 10/May/11 ]

Ok, so the proposal is to change each currently defined iterator (except RangeIterator) such that

From

XXXIterator extends RangeIterator {

to

XXXIterator extends RangeIterator, Iterable<XXX> {

Correct?

Comment by thomasmueller2 [ 11/May/11 ]

Yes, I think this is correct.

Comment by Peeter Piegaze [ 13/Sep/12 ]

Ok, I am back on JSR 333 (after a rather long hiatus). I intend to get this thing out the door ASAP.

So, on this issue: I am ready to make the changes to the interfaces as per my 10/May/11 comment above. Is everyone ok with this or will it blow up in our faces? I guess we will find out if there are technical problems at the ref impl stage and if there are we can still change the spec to accomodate that before the final product is released.

Comment by Peeter Piegaze [ 10/Oct/12 ]

Fixed as suggested

Comment by jukka.zitting [ 23/Oct/12 ]

-0.9, mixing Iterator with Iterable is quite troublesome, similar to the pain we got by making Value instances have state (see for example JSR_283-41).

Instead I'd propose that we keep the existing Iterator interfaces, and introduce parallel access methods that return Iterables. For example:

NodeIterator iterator = node.getNodes();
while (iterator.hasNext())

{ Node child = iterator.nextNode(); ...; }

vs.

for (Node child : node.nodes())

{ ...; }

As a simple naming pattern I propose that for a getFoos() method that returns an Iterator, we add a parallel foos() method that returns an Iterable.

A straightforward implementation of such a foos() method (assuming FooIterator extends Iterator<Foo>) would be:

public Iterable<Foo> foos() {
return new Iterable<Foo>() {
public Iterator<Foo> iterator()

{ return getFoos(); }

};
}

Or if an implementation already has an Iterable they can return from such a method, implementing the respective getFoos() method is even easier:

public FooIterator getFoos()

{ return foos().iterator(); }
Comment by rhauch [ 23/Oct/12 ]

The statefulness of Iterators does become tricky, especially if applications were written to obtain, hold onto, use each Iterable instance to obtain multiple Iterator instances. It becomes less tricky if applications just use the Iterable to support looping.

I could live with either approach. If we accept that additional methods be added to obtain the Iterables, then I do like Jukka's naming patterns.

Comment by thomasmueller2 [ 24/Oct/12 ]

For me, both is OK.

Even thought, I don't share the concern regarding iterators being stateful, because the method iterator() doesn't affect the internal state as far as I see. Also, we are not making this class stateful now (iterators are already stateful). I don't see how this is related to the Value class (yes I think it was a mistake to make Value stateful, and I wonder if this could be reversed).

But it is a bit weird that an Iterator is at the same time an Iterable. This might be confusing for users.

I wonder if we need to introduce new interfaces (NodeIterable and so on) or if we can use Iterable<Node> and so on.





[JSR_333-44] define event filtering on PERSIST events Created: 09/Dec/11  Updated: 16/Oct/12  Resolved: 16/Oct/12

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: reschke Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

As far as I can tell, JSR-283 is silent on how event filtering works with PERSIST events (which have a null path and no associated node).

It appears the obvious choice is to say that PERSIST events are excluded from filtering.



 Comments   
Comment by Peeter Piegaze [ 16/Oct/12 ]

I have added the following text to the section 12.6.3 of the spec:

PERSIST events are not subject to filtering since they are not associated with any particular node. They are, however, affected by the noLocal parameter in the sense that when noLocal is set to true, then no events (not even PERSIST events) are reported from the session through which the journal is accessed.





[JSR_333-50] NamespaceRegistry doesn't define constant for the http://www.jcp.org/jcr/sv/1.0 namespace Created: 19/Jul/12  Updated: 12/Oct/12  Resolved: 12/Oct/12

Status: Closed
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: anchela Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Text File JSR_333-50.patch    

 Description   

in section 7.2 System View the specification refers to the namespace http://www.jcp.org/jcr/sv/1.0
nevertheless and in contrast to other namespaces (jcr, nt, mix) mentioned by the specification this
namespace is not listed as constant in the NamespaceRegistry interface.



 Comments   
Comment by Peeter Piegaze [ 12/Oct/12 ]

Patch applied. Fixed





[JSR_333-52] javax.jcr.PropertyType.valueFromName(String):int should be case-insensitive Created: 10/Sep/12  Updated: 12/Oct/12  Resolved: 12/Oct/12

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: rhauch Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There is an inconsistence in the "nt:propertyDefinition" node type definition, which defines some of the content structure used when an implementation supports the optional feature to the "expose node types as content". The "jcr:requiredType" property definition is of type STRING and is defined as follows:

jcr:requiredType (STRING) protected mandatory
< 'STRING', 'URI', 'BINARY', 'LONG', 'DOUBLE',
'DECIMAL', 'BOOLEAN', 'DATE', 'NAME', 'PATH',
'REFERENCE', 'WEAKREFERENCE', 'UNDEFINED'

These constrained values do not match the String constants defined in javax.jcr.PropertyType. See http://java.net/jira/browse/JSR_283-811 for a longer discussion of the issue and potential ways of addressing it. Note that the javax.jcr.nodetypes.PropertyDefinition interface's "getRequiredType()" method returns an integer, so there is little (if any) JCR behavior that is dependent upon the (optional) "/jcr:system/jcr:nodeTypes" content. However, there is currently no standard method to convert the "jcr:requiredType" string values to a PropertyType, since the javax.jcr.PropertyType.valueFromName(String)" method is currently case-sensitive.

One option is to simply fix the constrained values, but that would make all nodes of type "nt:propertyDefinition" under "/jcr:system/jcr:nodeTypes" be invalid and require implementations to change these nodes upon upgrading from JSR-283 to JSR-333.

Alternatively, I propose leaving the constants in javax.jcr.PropertyType, leaving unchanged (relative to JSR-283) the constraints on "jcr:requiredType" property definition, and instead changing the "javax.jcr.PropertyType.valueFromName(String)" method to evaluate the supplied parameter in a case-insensitive manner. No other changes are proposed.



 Comments   
Comment by Peeter Piegaze [ 12/Oct/12 ]

Fixed as suggested.





[JSR_333-25] Java EE 7 Relations Created: 06/Mar/11  Updated: 10/Oct/12  Resolved: 10/Oct/12

Status: Closed
Project: jsr-333
Component/s: None
Affects Version/s: milestone 1
Fix Version/s: None

Type: Task Priority: Minor
Reporter: cat Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: enterprise, external

 Description   

While Java EE 6 still pointed to JSR-170, deferring it to a future release (http://jcp.org/en/jsr/detail?id=316) the current Java EE 7 proposal (http://jcp.org/en/jsr/detail?id=342) doesn't even mention JCR.

Is that in the interest of both the JCR and Java EE spec or was it simply forgotten? If any relationship with Java EE 7 or its contents was identified and desired, this task may act as an umbrella, unless everybody agreed there was no interest in it for this release of EE and JCR.



 Comments   
Comment by Peeter Piegaze [ 10/May/11 ]

Even if we wanted to, what could we as the JSR-333 EG do about this?

Comment by Peeter Piegaze [ 10/Oct/12 ]

No response. I think we can assume there is not enough interest in pursuing this issue. If anyone disagrees, please reopen.

Comment by Peeter Piegaze [ 10/Oct/12 ]

reopen...to close as wontfix

Comment by Peeter Piegaze [ 10/Oct/12 ]

wont fix





[JSR_333-29] Drop distinction between PathNotFoundException and ItemNotFoundException Created: 01/Jun/11  Updated: 10/Oct/12  Resolved: 10/Oct/12

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: anchela Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

i remember that this has been discussed before but didn't manage to find
the corresponding issue.

while in theory the distinction between PathNotFoundException and ItemNotFoundException makes sense, i have
the impression that it turns out to be quite artificial in reality. while working on the remoting of JCR
calls over http it even turned out to be impossible to distinguish them, which lead to pretty ugly code
in the JCR implementation: catching PathNotFoundException and rethrowing it as ItemNotFoundException (or vice
versa) just because of the mere fact that the JCR API mandated the other exception.

would it be feasible to merge the two exceptions? or make either of them a subclass of the other?



 Comments   
Comment by Peeter Piegaze [ 30/Jun/11 ]

What would the backward compatibility implications of this be? Does anyone have a clear idea?

Comment by stefan_guggisberg [ 01/Jul/11 ]

this seems to be a pure implementation issue and
jsr-333 OTOH focuses on improving useability of the JCR api.

while i agree that the distinction is artificial i am not sure
whether it's worth changing the api/class hierarchy at this
point.

i'm -0 for doing such changes.

Comment by Peeter Piegaze [ 10/Oct/12 ]

There seems to be no further argument here, so I will close this as wontfix





[JSR_333-54] Misspelled method name "Node.getAllowedLifecycleTransistions" Created: 09/Oct/12  Updated: 10/Oct/12  Resolved: 10/Oct/12

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The method

Node.getAllowedLifecycleTransistions

should really be

Node.getAllowedLifecycleTransitions

(i.e., without the extra 's')

To correct this typo we should deprecate the misspelled method and add a correctly spelled equivalent.



 Comments   
Comment by Peeter Piegaze [ 10/Oct/12 ]

Misspelled method deprecated and correctly spelled method added





[JSR_333-18] Add convenient access to property value from node Created: 07/Nov/10  Updated: 09/Oct/12  Resolved: 09/Oct/12

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: uncled Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 18

 Description   

In Apache Sling we added a method that allows access to the Value of a property
in a convenient way.

http://sling.apache.org/apidocs/sling5/org/apache/sling/api/resource/ValueMap.html

I would like to propose that we add something similar to the Node interface that
allows access (potentially even straight to the string representation of the value).



 Comments   
Comment by uncled [ 07/Nov/10 ]

Since there are various approaches, i think this may be valuable to discuss in
next weeks conference call.

Comment by Peeter Piegaze [ 12/Jan/11 ]

Changed platform to "All"

Comment by thomasmueller2 [ 29/Mar/11 ]

I like it. Similar features are added to other API, for example the JDBC API in Java 7:
<T> T ResultSet.getObject(int columnIndex, Class<T> type).
This feature doesn't always result in less code for the user. It depends what we support exactly:

Old style:
String x = n.getProperty("x").getString();

New style 1:
String x = n.get("x", String.class);

New style 2:
String x = n.getProperty("x").get(String.class);

New style 3:
String x = n.getPropertyObject("x", String.class);

However there is a clear advantage when using the default value:

Old style:
String x = n.hasProperty("x") ? n.getProperty("x").getString() : "default";

New style 1:
String x = n.get("x", "default");

New style 2:
String x = n.getProperty("x").get("default");

New style 3:
String x = n.getPropertyObject("x", "default");

Where the new methods for each style would be (I hope it's correct):

New style 1:
Node

{ <T> T get(String propertyName, Class<T> type); <T> T get(String propertyName, T defaultValue); }

New style 2:
Property

{ <T> T get(Class<T> type); <T> T get(T defaultValue); }

New style 3:
Node

{ <T> T getPropertyObject(String propertyName, Class<T> type); <T> T getPropertyObject(String propertyName, T defaultValue); }
Comment by stefan_guggisberg [ 30/Mar/11 ]

in general i agree to adding convenience methods
for reading property values.

if we're going to add such methods to the Node interface,
i suggest that, for consistency reasons, we use a name like
e.g. 'getPropertyValue' rather than just 'get'. 'getPropertyObject',
as suggested by thomas, would IMO be somehow misleading.

those methods would need to be carefully spec'ed WRT to e.g.:

  • access control
  • MVP
  • unsupported type conversion

assume we've got a string property "foo" with a value "bar".
what would be the outcome of the following call?

Integer int = someNode.getPropertyValue("foo", new Integer(313));

Comment by thomasmueller2 [ 30/Mar/11 ]

I used getPropertyObject because I think a user would expect getPropertyValue to return a javax.jcr.Value, whereas in fact the method returns an Object.

someNode.getPropertyValue("foo", new Integer(313));

(by the way this is the same as: someNode.getPropertyValue("foo", 313)) I think this should internally call getProperty("foo").getLong(), so it should throw: javax.jcr.ValueFormatException: "not a long: bar".

Another question is: what happens if the property does contain a long, but the long is too large to fit in an int. Currently casting from BigDecimal("100000000000000000000000000") to long (in Jackrabbit) results in -2537764290115403776. Not sure if that's the expected behavior.

Comment by Peeter Piegaze [ 04/May/11 ]

Does this make sense?

Node

{ public <T> T getPropertyAs(String propertyName, Class<T> type); public <T> T getPropertyAs(String propertyName, T defaultValue); public String getPropertyAsString(String propertyName); public <T> T[] getPropertyAsArray(String propertyName, Class<T> type); public String[] getPropertyAsArray(String propertyName); }
Comment by Peeter Piegaze [ 04/May/11 ]

Trying again:

public <T> T getPropertyAs(String propertyName, Class<T> type);

public <T> T getPropertyAs(String propertyName, T defaultValue);

public String getPropertyAsString(String propertyName);

public <T> T[] getPropertyAsArray(String propertyName, Class<T> type);

public String[] getPropertyAsArray(String propertyName);

Comment by stefan_guggisberg [ 05/May/11 ]

the naming is IMO inconsistent, e.g.

String getPropertyAsString(String propertyName);

vs

String[] getPropertyAsArray(String propertyName);

supporting MVPs makes it IMO unfortunately kind of
awkward and counterintuitive. what is the expected
result of calling getPropertyAsArray on a SVP and
getPropertyAs on a MVP?

since i can't come up with a better/more elegant way
of supporting the original proposal i'm voting -0 for
this proposal.

Comment by thomasmueller2 [ 05/May/11 ]

Personally, I would prefer the much simpler method name "get":
public <T> T get(String propertyName, Class<T> type);
public <T> T get(String propertyName, T defaultValue);

I don't think I would use special methods for String, instead I would use:
String s = n.get("name", "");

But if you prefer not to use "get":

This is OK:
String s = n.getPropertyAs("name", String.class);
String s = n.getPropertyAsString("name");

This sounds weird:
String s = n.getPropertyAs("name", "-");
what about:
String s = n.getPropertyWithDefault("name", "-");

This method isn't required:
public <T> T[] getPropertyAsArray(String propertyName, Class<T> type);
String[] s = n.getPropertyAsArray("names", String.class);
because it is already available using
public <T> T getPropertyAs(String propertyName, Class<T> type):
String[] s = n.getPropertyAs("names", String[].class);

I believe the following method isn't important:
public String[] getPropertyAsArray(String propertyName);
but if you think it is, then it should be:
public String[] getPropertyAsStringArray(String propertyName);

Comment by Peeter Piegaze [ 02/Oct/12 ]

Ok then (getting back to this long-hibernating topic), I propose to add the following methods to Node:

public <T> T getPropertyAs(String propertyName, Class<T> type);

public String getPropertyAsString(String propertyName)

public String[] getPropertyAsStringArray(String propertyName);

public <T> T getPropertyWithDefault(String propertyName, T defaultValue);

Comment by Peeter Piegaze [ 09/Oct/12 ]

Fixed as suggested by Thomas.





[JSR_333-24] Review System Requirements in Spec Document Created: 06/Mar/11  Updated: 09/Oct/12  Resolved: 09/Oct/12

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: current
Fix Version/s: None

Type: Task Priority: Minor
Reporter: cat Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: doc

 Description   

While not a bug as such, I was wondering when going through the Word file jcr-spec.doc if

>1.4 System Requirements
>The JCR 2.1 requires Java Runtime Environment (JRE) 1.4 or greater.

was simply a Copy&Paste case from previous versions, or if the foundation was really still Java 1.4 with no feature of Java 5 being used or considered?



 Comments   
Comment by thomasmueller2 [ 06/Mar/11 ]

I'm not sure if its necessary to change this statement, because Java 1.4 applications can still be supported even if the API uses Java 5 features such as generics. JSR_333-18 uses generics, but the API in theory is still compatible with Java 1.4.

But probably it's simpler to require Java 5, because that would simplify testing.

Comment by Peeter Piegaze [ 10/May/11 ]

Proposal:

Change

>1.4 System Requirements
>The JCR 2.1 requires Java Runtime Environment (JRE) 1.4 or greater.

to

>1.4 System Requirements
>The JCR 2.1 requires Java Runtime Environment (JRE) 5.0 or greater.

Can we agree to this change?

Comment by thomasmueller2 [ 11/May/11 ]

+1 for "requires Java Runtime Environment (JRE) 5.0 or greater."

Comment by Peeter Piegaze [ 09/Oct/12 ]

Fixed as suggested.





[JSR_333-7] Improve client-server awareness Created: 01/Sep/10  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 7

 Description   

One of the goals of JSR 333 is to improve client-server awareness in JCR. I am opening this issue as a
container for suggestions on how to do that. Individual improvements that we agree upon can then get
their own issues later.



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Enhancement

Comment by Peeter Piegaze [ 13/Sep/12 ]

Any suggestions with regard to this issue are welcome. There are probably quite a few areas where our experience with jackrabbit can tell us about imporvements in terms of client/server awareness.

Comment by Peeter Piegaze [ 02/Oct/12 ]

No input. Setting to Won't Fix





[JSR_333-10] Node type library Created: 01/Sep/10  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Task Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 10

 Description   

One of the suggestions deferred from JCR 2.0 to 2.1 was the issue of a node type library. I'd like to call for
suggestions on how to handle this issue within the scope of this JSR, if at all.



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Task

Comment by Peeter Piegaze [ 02/Oct/12 ]

No Input. Resolving as wont' fix.





[JSR_333-6] Scripting support of the API Created: 01/Sep/10  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 6

 Description   

One of the goals of JSR 333 is to provide scripting support in JCR. I am opening this issue as a container
for suggestions on how to do that. Individual improvements that we agree upon can then get their own
issues later.



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Enhancement

Comment by Peeter Piegaze [ 02/Oct/12 ]

No input. Resolving as Won't fix





[JSR_333-11] Internationalization Created: 01/Sep/10  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 11

 Description   

One of the issues deferred from 2.0 to 2.1 was that of internationalization. I'm opening this issue as a
container for suggestions on places in the API where support for this can be added. Later we can break out
individual changes as their own issues.



 Comments   
Comment by Peeter Piegaze [ 02/Oct/12 ]

No input. Resolving as Won't Fix





[JSR_333-9] Maintenance container Created: 01/Sep/10  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Bug Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issue Links:
Dependency
depends on JSR_333-21 Clarification of terms: "access contr... Resolved
Issuezilla Id: 9

 Description   

One of the goals of JSR 333 is to fix problems and mistakes made in JCR 2.0. I am opening this issue as a
container for suggestions on things that need fixing. Individial fixes can be broken out into their own
issues later.



 Comments   
Comment by Peeter Piegaze [ 02/Oct/12 ]

Resolving as we have specific issues addressing errors already





[JSR_333-5] Lower entry barriers for implementers and application developers Created: 01/Sep/10  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 5

 Description   

One of the goals of JSR 333 is to lower the entry barriers to JCR. I am opening this issue as a container for
suggestions on how to do that. Individual improvements that we agree upon can then get their own issues
later.



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Enhancement

Comment by Peeter Piegaze [ 13/Sep/12 ]

Any suggestions in the realm of lowering entry barriers?

Comment by Peeter Piegaze [ 02/Oct/12 ]

Resolving won't fix





[JSR_333-4] Improve ease-of-use of API Created: 01/Sep/10  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issue Links:
Dependency
depends on JSR_333-26 Simplify ObservationManager.addEventL... Resolved
Issuezilla Id: 4

 Description   

One of the general goals of JSR 333 is to improve the ease-of-use of the JCR API. I am opening this issue
as a container for suggestions on how to achieve that goal. Individual improvements that we agree upon
can then get their own issues later.



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Enhancement

Comment by dbu [ 15/Feb/11 ]

maybe this can be used as an inspiration:
https://github.com/jackalope/phpcr/blob/master/doc/JCR_TO_PHPCR.txt

we did some changes while porting jcr to php. php being a scripting language, ease of use is a great concern and thus we simplified quite a bit.

Comment by Peeter Piegaze [ 13/Sep/12 ]

Hi dbu,

That link is dead, can you give me a new one?

If anyone has any other ideas for ease-of-use enhancements (for example, we already have the "make iterators iterable" issue going ahead) please speak up.

Comment by Peeter Piegaze [ 02/Oct/12 ]

Resolving this issue, since it is a general one regarding ease of use and nothing specific





[JSR_333-40] AccessControlManager interface out of sync with spec Created: 10/Aug/11  Updated: 02/Oct/12  Resolved: 02/Oct/12

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: anchela Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

the AccessControlManager interface has not yet been updated to reflect the
changes made for JSR_333-15.



 Comments   
Comment by Peeter Piegaze [ 26/Oct/11 ]

Fixed: The javadoc in src has been updated as suggested.

Comment by anchela [ 06/Jun/12 ]

reopening as Privilege.java still doesn't define constants for the new privileges.
in addition javadoc of Privilege#JCR_ALL should list the new privileges in the description of
the aggregation.

Comment by Peeter Piegaze [ 02/Oct/12 ]

The changes have already been made.





[JSR_333-3] Define MIME type for CND Created: 01/Sep/10  Updated: 13/Sep/12  Resolved: 13/Sep/12

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 3

 Description   

JSR 283 issue #400 was deferred to JCR 2.1. Below is a copy of the comments from the 283 issue:

------

I think it would be extremely useful to define a MIME type for CND.

Things to do related to this:

  • embed a IANA registration form into the spec (see RFC4288),
  • clarify format when stored in a binary object (such as a file) – what is the
    encoding?
              • Additional comments from ppiegaze Wed Jul 23 22:46:15 +0000 2008 -------

As per costamesa F2F, defer to JCR 2.1



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Enhancement

Comment by Peeter Piegaze [ 25/Mar/11 ]

Julian,

How exactly does one register a new MIME type?

Comment by Peeter Piegaze [ 25/Mar/11 ]

Ok, I found the form. Would including the following in an Appendix in the spec be a good start? (please feel free to suggest any improvements)

David Nuescheler
david.nuescheler@adobe.com

Media Type Name: text

Subtype name: jcr-cnd

Required parameters: none

Optional parameters: none

Encoding considerations: 8 bit (UTF-8)

Security considerations: none known

Interoperability considerations: none

Published specification: http://jcp.org/en/jsr/detail?id=283

Applications which use this media type: Used by content repositories that implement the Content Repository For Java API (JCR).

File extension: .cnd

Intended usage: Files of this media type define node types in JCR-compliant content repositories. Nodes are the structural components that make up the content storage in a JCR repository. A node type defines the characteristics that a node can have. Files of this media type are typically processed by a repository, thus registering the defined node types, making them available to users of the repository. Files of this media type are typically referred to as Compact Node Type Definition files or CND files.

Person to contact for further information:
David Nuescheler
Adobe Systems
david.nuescheler@adobe.com

Comment by reschke [ 25/Mar/11 ]

...<http://tools.ietf.org/html/rfc4288#section-5>

So yes, put the form into the appendix, and send it for review to ietf-types@iana.org.

I'll help from there.

Comment by Peeter Piegaze [ 28/Mar/11 ]

I have submitted a slightly altered form of MIME type registration notice (reproduced below) to IANA. The notice has also been added to the appendix of the spec. I will leave this issue open to track the progress of the request.

=====
Media Type Name: text

Subtype name: jcr-cnd

Required parameters: None.

Optional parameters: None.

Encoding considerations: 8 bit (UTF-8).

Security considerations: None known.

Interoperability considerations: None.

Published specification: http://jcp.org/en/jsr/detail?id=283. See especially sections 3.7 and 25.2.

Applications which use this media type: Used by content repositories that implement the Content Repository For Java API (JCR).

File extension: .cnd

Intended usage: Files of this media type define node types in JCR-compliant content repositories. Nodes are the structural components that make up the content storage in a JCR repository. A node type defines the characteristics that a node can have. Files of this media type are typically processed by a repository, thus registering the defined node types, making them available to users of the repository. Files of this media type are typically referred to as Compact Node Type Definition files or CND files.

Persons to contact for further information:
David Nuescheler
Adobe Systems
uncled@adobe.com

Peeter Piegaze
Adobe Systems
ppiegaze@adobe.com

Comment by Peeter Piegaze [ 04/May/11 ]

Julian,

I made the submission. Is there something more to do?

Comment by reschke [ 04/May/11 ]

Did you also send to iesg@ietf.org?

Comment by Peeter Piegaze [ 05/May/11 ]

> Did you also send to iesg@ietf.org?

Well, no. Who or what is that? I assume you are saying that I should?

Comment by reschke [ 05/May/11 ]

From RFC 4288, Section 5:

5. Registration Procedure

The media type registration procedure is not a formal standards
process, but rather an administrative procedure intended to allow
community comment and sanity checking without excessive time delay.

The normal IETF processes should be followed for all IETF
registrations in the standards tree. The posting of an Internet
Draft is a necessary first step, followed by posting to the
ietf-types@iana.org list as discussed below.

Registrations in the vendor and personal tree should be submitted
directly to the IANA, ideally after first posting to the
ietf-types@iana.org list for review.

Proposed registrations in the standards tree by other standards
bodies should be communicated to the IESG (at iesg@ietf.org) and to
the ietf-types list (at ietf-types@iana.org). Prior posting as an
Internet Draft is not required for these registrations, but may be
helpful to the IESG and is encouraged.

The IESG is the Internet Engineering Steering Group, see <http://www.ietf.org/iesg/>.

As our media type isn't defined in an IETF document, and the JSR qualifies as external standard body, they will have to review the registration and approve it. The mail to the ietf-types list was to get community feedback.

Comment by Peeter Piegaze [ 06/May/11 ]

Ok. I understand. I will submit it to iesg@ietf.org

Comment by Peeter Piegaze [ 06/Mar/12 ]

Since the approval procedure for this mimetype has become stuck, I have re-submitted it to ietf-types@iana.org and iesg@ietf.org.

We'll see what happens

Comment by Peeter Piegaze [ 13/Sep/12 ]

The mime type text/jcr-cnd has been registered with the IANA. See http://www.iana.org/assignments/media-types/text/jcr-cnd.





[JSR_333-48] Add a Session.getNodesByIdentifier () method to the API Created: 27/Feb/12  Updated: 06/Mar/12  Resolved: 06/Mar/12

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Christian Stocker Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Similar to JSR_333-38 with NodeIterator Session.getNodes(String[] absPaths) method, we should add a

NodeIterator Session.getNodesByIdentifier(String[] Identifier)

method.

We already have "Node Session.getNodeByIdentifier(String identifier)", so this would make it consistent.



 Comments   
Comment by Peeter Piegaze [ 06/Mar/12 ]

Method added.





[JSR_333-46] Add support for registering node types defined in CND file Created: 24/Jan/12  Updated: 29/Feb/12  Resolved: 29/Feb/12

Status: Resolved
Project: jsr-333
Component/s: api, spec
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: rhauch Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There is no way to use the standard JCR 2.0 (JSR-283) API to load node type definitions from a CND file, even though the CND file format was standardized as part of JSR-283. Instead, implementation-specific techniques or non-standard utilities must be used to parse the CND file into NodeTypeDefinition instances, and then the current NodeTypeManager.registerNodeTypes(NodeTypeDefinition[], boolean) method must be called.

I propose that one three new method be added to NodeTypeManager to enable JCR clients to use the standard JCR 2.1 API to register the node type definitions within one or more CND files. The three new methods is are similar to the registerNodeTypes(NodeTypeDefinition[] ntds, boolean allowUpdate) method that existed in JCR 2.0, except that it has as the first parameter an InputStream containing the CND content. and the three new method vary only in the first parameter that defines the CND content: by InputStream, by java.net.URL, and by java.io.File.

The benefit for developers of JCR client applications is clear and substantial. On the other hand, the cost to implementers is likely minimal, since JCR 2.0 implementations likely can already read the CND files and create the NodeTypeDefinition instances, and they can implement the these new method by then delegating to the existing registerNodeTypes(NodeTypeDefinition[],boolean) method.

/**
 * Registers or updates the node type definitions per the Compact Node Definition
 * (CND) file given by the supplied stream. This method is used to register 
 * or update a set of node types with mutual dependencies. Returns an iterator
 * over the resulting <code>NodeType</code> objects.
 * <p>
 * The effect of the method is "all or nothing"; if an error occurs, no node
 * types are registered or updated.
 * </p>
 *
 * @param stream the stream containing the node type definitions in CND format
 * @param allowUpdate a boolean stating whether existing node type definitions should be modified/updated
 * @return the registered node types.
 * @throws IOException if there is a problem reading from the supplied stream
 * @throws InvalidNodeTypeDefinitionException
 *                                 if a <code>NodeTypeDefinition</code>
 *                                 within the <code>Collection</code> is invalid or if the
 *                                 <code>Collection</code> contains an object of a type other than
 *                                 <code>NodeTypeDefinition</code>.
 * @throws NodeTypeExistsException if <code>allowUpdate</code> is
 *                                 <code>false</code> and a <code>NodeTypeDefinition</code> within the
 *                                 <code>Collection</code> specifies a node type name that is already
 *                                 registered.
 * @throws UnsupportedRepositoryOperationException
 *                                 if this implementation
 *                                 does not support node type registration.
 * @throws RepositoryException     if another error occurs.
 * @since JCR 2.1
 */
NodeTypeIterator registerNodeTypes( InputStream stream,
                                    boolean allowUpdate )
    throws IOException, InvalidNodeTypeDefinitionException, NodeTypeExistsException, 
    UnsupportedRepositoryOperationException, RepositoryException;

UPDATE BY RMH: Previously, two other methods were proposed, but comments/feedback suggested they were superfluous. So these methods are no longer proposed to be included in the API:

/**
 * Registers or updates the node type definitions per the Compact Node Definition
 * (CND) file given by the supplied file. This method is used to register 
 * or update a set of node types with mutual dependencies. Returns an iterator
 * over the resulting <code>NodeType</code> objects.
 * <p>
 * The effect of the method is "all or nothing"; if an error occurs, no node
 * types are registered or updated.
 * </p>
 *
 * @param file the file containing the node types
 * @param allowUpdate a boolean stating whether existing node type definitions should be modified/updated
 * @return the registered node types.
 * @throws IOException if there is a problem reading from the supplied stream
 * @throws InvalidNodeTypeDefinitionException
 *                                 if a <code>NodeTypeDefinition</code>
 *                                 within the <code>Collection</code> is invalid or if the
 *                                 <code>Collection</code> contains an object of a type other than
 *                                 <code>NodeTypeDefinition</code>.
 * @throws NodeTypeExistsException if <code>allowUpdate</code> is
 *                                 <code>false</code> and a <code>NodeTypeDefinition</code> within the
 *                                 <code>Collection</code> specifies a node type name that is already
 *                                 registered.
 * @throws UnsupportedRepositoryOperationException
 *                                 if this implementation
 *                                 does not support node type registration.
 * @throws RepositoryException     if another error occurs.
 * @since JCR 2.1
 */
NodeTypeIterator registerNodeTypes( File file,
                                    boolean allowUpdate ) 
    throws IOException, InvalidNodeTypeDefinitionException, NodeTypeExistsException, 
    UnsupportedRepositoryOperationException, RepositoryException;

/**
 * Registers or updates the node type definitions per the Compact Node Definition
 * (CND) file given by the supplied URL. This method is used to register 
 * or update a set of node types with mutual dependencies. Returns an iterator
 * over the resulting <code>NodeType</code> objects.
 * <p>
 * The effect of the method is "all or nothing"; if an error occurs, no node
 * types are registered or updated.
 * </p>
 *
 * @param url the URL that can be resolved to the file containing the node type definitions in CND format
 * @param allowUpdate a boolean stating whether existing node type definitions should be modified/updated
 * @return the registered node types.
 * @throws IOException if there is a problem reading from the supplied stream
 * @throws InvalidNodeTypeDefinitionException
 *                                 if a <code>NodeTypeDefinition</code>
 *                                 within the <code>Collection</code> is invalid or if the
 *                                 <code>Collection</code> contains an object of a type other than
 *                                 <code>NodeTypeDefinition</code>.
 * @throws NodeTypeExistsException if <code>allowUpdate</code> is
 *                                 <code>false</code> and a <code>NodeTypeDefinition</code> within the
 *                                 <code>Collection</code> specifies a node type name that is already
 *                                 registered.
 * @throws UnsupportedRepositoryOperationException
 *                                 if this implementation
 *                                 does not support node type registration.
 * @throws RepositoryException     if another error occurs.
 * @since JCR 2.1
 */
NodeTypeIterator registerNodeTypes( URL url,
                                    boolean allowUpdate ) 
    throws IOException, InvalidNodeTypeDefinitionException, NodeTypeExistsException, 
    UnsupportedRepositoryOperationException, RepositoryException;


 Comments   
Comment by stefan_guggisberg [ 25/Jan/12 ]

i agree in general with adding support for registering node types defined in the CND format.

some (minor) issues:

  • CND is defined in the appendix of the JCR 2.0 specification, hence it's "non-normative".
    i guess we'll have to 'promote' the CND format to be normative or add some clarifying
    language.
  • i don't think that we need 3 separate signatures. registerNodeTypes(InputStream stream, boolean allowUpdate)
    should be perfectly fine since getting an InputStream from a File (FileInputStream) or
    URL (URL#openStream()) is trivial.
Comment by rhauch [ 25/Jan/12 ]

Regarding the 3 signatures, I almost proposed just the one, but thought the URL and File forms are indeed useful and worth giving it a shot considering that those are likely to be the most used in real deployments. Two additional methods in an API don't seem a burden for implementers, but it does IMO make it easier and more intuitive for client developers (which seems like the primary goal of the API).

If consensus is to have just one, then that's fine.

Comment by thomasmueller2 [ 26/Jan/12 ]

Hi,

This is a nice feature!

In my view, just one method (registerNodeTypes(InputStream stream, boolean allowUpdate)) is sufficient, for the reasons outlined by Stefan.

Regards,
Thomas

Comment by rhauch [ 26/Jan/12 ]

Okay, I've amended the description above to propose adding only the one method that takes an InputStream as the first parameter.

Any other questions or concerns about the suggested signature and JavaDoc?

Comment by Peeter Piegaze [ 29/Feb/12 ]

I will add the new signature (the Inputstream only) and explanation to the source and spec.

Comment by Peeter Piegaze [ 29/Feb/12 ]

Fixed: new signature added to spec and source





[JSR_333-41] make javadoc of Property.setValue(Value value) more explicit Created: 11/Aug/11  Updated: 14/Oct/11  Resolved: 13/Oct/11

Status: Closed
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: dbu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

the javadoc [1] tells that "If the property type is constrained, then a best-effort conversion is attempted." however, the jcr 2.0 specification defines in 3.6.4 [2] an exact list of what can be converted into which types and when to throw the ValueFormatException.

the best-effort conversion suggerates that the implementation might convert more of the cases or "just does something" like convert string "hello" to integer 1. according to stefan guggisberg, this is not the intention. best-effort in this case means that a conversion is attempted but it's not guaranteed to succeed.

i suggest referencing the spec at paragraph 3.6.4 in the javadoc to be exact what behaviour to expect. something like "...then a conversion according to JCR specification, paragraph 3.6.4 is attempted."

if the implementations don't follow the exact same rules, this will result in non-portable client code because what works with one implementation works not with an other.

see also https://github.com/phpcr/phpcr-api-tests/issues/27



 Comments   
Comment by dbu [ 12/Aug/11 ]

similar comments are on Node.setProperty(string, Value) as well.

Comment by Peeter Piegaze [ 13/Oct/11 ]

CHanges made to Property.setValue and Node.setProperty Javadoc as suggested

Comment by dbu [ 14/Oct/11 ]

thanks peter





[JSR_333-42] deprecate Item#refresh(boolean) Created: 28/Sep/11  Updated: 13/Oct/11  Resolved: 13/Oct/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: stefan_guggisberg Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

i propose to deprecate the Item#refresh(boolean) method.

it's difficult to implement (e.g. with a MVCC-based backend)
and i can't come up with a legitimate use case requiring
Item.refresh(boolean) instead of Session#refresh(boolean).

its cousin Item#save() has already been deprecated as of JCR 2.0



 Comments   
Comment by Peeter Piegaze [ 13/Oct/11 ]

+1 to this.

This seems uncontroversial so unless someone objects, I will make the change

Comment by Peeter Piegaze [ 13/Oct/11 ]

Fixed as suggested.





[JSR_333-39] Missing constants for privileges introduced in JSR_333-15 Created: 10/Aug/11  Updated: 10/Aug/11  Resolved: 10/Aug/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: anchela Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JSR_333-15 introduces some new privileges, but they didn't make it
as constants into the Privilege.java interface.
similarly the jcr:all privilege definition doesn't list those new privileges.






[JSR_333-19] Provide a Workspace#removeItem(String) method Created: 15/Nov/10  Updated: 05/Jul/11  Resolved: 05/Jul/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: stefan_guggisberg Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 19

 Description   

currently it's only possible to remove an item/subtree transiently through Session#removeItem(String) or
Item#remove(); i.e. the changes have to be persisted by calling save().

removing a huge subtree can be problematic for some implementations since the changes have to be
recorded in transient space.

a Workspace#removeItem(String) would allow an implementation to efficiently handle to use case of
deleting a huge subtree. it would be a workspace-write method and the changes would be persisted
immediately.

olease note that this enhancement has been suggested before in jsr-283 (https://jsr-
283.dev.java.net/issues/show_bug.cgi?id=405), unfortunately it's been misinterpreted (https://jsr-
283.dev.java.net/issues/show_bug.cgi?id=550).



 Comments   
Comment by Peeter Piegaze [ 04/May/11 ]

This seems like a change that is small but quite useful.

Unless someone objects I will make the appropriate changes in src and spec.

Comment by Peeter Piegaze [ 05/Jul/11 ]

Method added.





[JSR_333-26] Simplify ObservationManager.addEventListener Created: 07/Mar/11  Updated: 30/Jun/11  Resolved: 30/Jun/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: thomasmueller2 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Dependency
blocks JSR_333-4 Improve ease-of-use of API Resolved

 Description   

The method takes 7 parameters, which is not very user friendly:

ObservationManager.addEventListener(EventListener listener, int eventTypes, java.lang.String absPath, boolean isDeep, java.lang.String[] uuid, java.lang.String[] nodeTypeName, boolean noLocal)

An alternative would be to use the builder pattern:

EventFilter filter = observationManager.createEventFilter().setEventTypes(eventTypes).setAbsPath(absPath).
setDeep(isDeep).setIdentifiers(uuids).setNodeTypes(nodeTypeName).setNoLocal(noLocal);
observationManager.addEventListener(listener, filter);

The EventFilter could also be used for ObservationManager.getEventJournal(EventFilter filter).

Those are the only two methods I propose to add.

Just for reference, other methods with many parameter:

5:

ObservationManager.getEventJournal(int eventTypes, java.lang.String absPath, boolean isDeep, java.lang.String[] uuid, java.lang.String[] nodeTypeName)

LockManager.lock(java.lang.String absPath, boolean isDeep, boolean isSessionScoped, long timeoutHint, java.lang.String ownerInfo)

4:

Session.exportDocumentView(java.lang.String absPath, org.xml.sax.ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)

Session.exportDocumentView(java.lang.String absPath, java.io.OutputStream out, boolean skipBinary, boolean noRecurse)

Session.exportSystemView(java.lang.String absPath, org.xml.sax.ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)

Session.exportSystemView(java.lang.String absPath, java.io.OutputStream out, boolean skipBinary, boolean noRecurse)

VersionManager.merge(java.lang.String absPath, java.lang.String srcWorkspace, boolean bestEffort, boolean isShallow)

Workspace.clone(java.lang.String srcWorkspace, java.lang.String srcAbsPath, java.lang.String destAbsPath, boolean removeExisting)



 Comments   
Comment by Peeter Piegaze [ 28/Mar/11 ]

This issue falls under the ease-of-use category that we established as a goal of JCR 2.1

Comment by Peeter Piegaze [ 10/May/11 ]

Proposal: Add the following methods to Observation Manager and add the following new Interface, EventFilter:

public interface ObservationManager {

/**

  • Adds an <code>EventListener</code> with the characteristics as specified in the passed <code>EventFilter</code>.
  • Has the same effect as {@link #addEventListener(EventListener listener, int eventTypes, String absPath, boolean isDeep, String[] uuid, String[] nodeTypeName, boolean noLocal)}

    .
    *

  • @param listener an {@link EventListener}

    object.

  • @param filter an {@link EventFilter} object.
    * @throws RepositoryException If an error occurs.
    */
    public void addEventListener(EventListener listener, EventFilter filter) throws RepositoryException;

    /**
    * Retrieves the event journal for this workspace filtered by the passed <code>EventFilter</code>.
    * This method behaves the same as {@link #getEventJournal(int eventTypes, String absPath, boolean isDeep, String[] uuid, String[] nodeTypeName)}.
    * @param filter an {@link EventFilter}

    object.

  • @throws RepositoryException If an error occurs.
    */
    public void getEventJournal(EventFilter filter) throws RepositoryException;

/**

  • Creates an {@link EventFilter}

    that can then be configured and passed to the method

    {@link #addEventListener}

    .
    *

  • @return an <code>EventFilter</code>.
    */
    public EventFilter createEventFilter();

}

/**

  • An EventFilter object.
  • <p>
  • A storage object for event filter configuration. A blank EventFilter is
  • acquired through {@link ObservationManager#createEventFilter()}

    .

  • The parameters of the filter can then be set by chaining the set methods,
  • since each method returns the same EventFilter with indicated parameter set.
  • <p>
  • Note that since each method returns the same EventFilter with appropriate parameter set,
  • the set methods can be chained.
    */
    public interface EventFilter {

/**

  • Sets the <code>eventTypes</code> parameter of the filter.
  • See {@link ObservationManager#addEventListener} for information on this parameter.
    * If left unset, this parameter defaults to <code>null</code>.
    * @param eventTypes an <code>int</code>.
    * @return This EventListener object with the <code>eventTypes</code> parameter set.
    */
    public EventFilter setEventTypes(int eventTypes);

    /**
    * Sets the <code>absPath</code> parameter of the filter.
    * See {@link ObservationManager#addEventListener}

    for information on this parameter.

  • If left unset, this parameter defaults to <code>null</code>.
  • @param absPath an absolute path <code>String</code>.
  • @return This EventListener object with the <code>absPath</code> parameter set.
    */
    public EventFilter setAbsPath(String absPath);

/**

  • Sets the <code>isDeep</code> parameter of the filter.
  • See {@link ObservationManager#addEventListener} for information on this parameter.
    * If left unset, this parameter defaults to <code>false</code>.
    * @param isDeep a <code>boolean</code>.
    * @return This EventListener object with the <code>isDeep</code> parameter set.
    */
    public EventFilter setDeep(boolean isDeep);

    /**
    * Sets the <code>uuids</code> parameter of the filter.
    * See {@link ObservationManager#addEventListener}

    for information on this parameter.

  • If left unset, this parameter defaults to <code>null</code>.
  • @param uuids a <code>String</code> array.
  • @return This EventListener object with the <code>uuids</code> parameter set.
    */
    public EventFilter setIdentifiers(String[] uuids);

/**

  • Sets the <code>nodeTypeName</code> parameter of the filter.
  • See {@link ObservationManager#addEventListener} for information on this parameter.
    * If left unset, this parameter defaults to <code>null</code>.
    * @param nodeTypeName a <code>String</code> array.
    * @return This EventListener object with the <code>nodeTypeName</code> parameter set.
    */
    public EventFilter setNodeTypes(String[] nodeTypeName);

    /**
    * Sets the <code>noLocal</code> paremeter of the filter.
    * See {@link ObservationManager#addEventListener}

    for infomration on this parameter.

  • If left unset, this parameter defaults to <code>false</code>.
  • @param noLocal a <code>boolean</code>.
  • @return This EventListener object with the <code>noLocal</code> parameter set.
    */
    public EventFilter setNoLocal(boolean noLocal);
    }
Comment by Peeter Piegaze [ 10/May/11 ]

As for the other methods with many params, I suggest that we could create a similar LockParam interface for the final 4 parameters of the lock method (apart from the path).

For the other examples given (the four param ones), I think we should just leave them as is.

Comment by thomasmueller2 [ 11/May/11 ]

I think this is a very good solution. Should the EventFilter class also contain the getter methods?

Comment by Peeter Piegaze [ 30/Jun/11 ]

fixed.





[JSR_333-30] Clarify NamespaceRegistry#unregisterNamespace(String prefix) Created: 08/Jun/11  Updated: 30/Jun/11  Resolved: 30/Jun/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: anchela Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

based on a recent issue in jackrabbit [1] i was wondering why the prefix
is passed to the unregisterNamespace method instead of the uri (that is
apparently what i had expected without even taking notice of the fact
that it is the prefix

to me that looks a bit awkward since the prefix might be remapped in a
given session. thus, in order to unregister a namespace a given session
would need to find out the original prefix as stored in the namespace
registry and use that one for the unregistration... from that point of
view using the uri would feel natural to me.

[1] https://issues.apache.org/jira/browse/JCR-2984



 Comments   
Comment by stefan_guggisberg [ 16/Jun/11 ]

i agree that unregisterNamespace(String uri) would probably have been more intuitive.

however, IMO we can't change the spec of said method without compromising backwards compatibility.

AFAIU the prefix to be passed to unregisterNamespace(String prefix) refers to the
current session's prefix<->uri mappings, i.e. a client could use the following workaround
to unregister a namespace by uri:

NamespaceRegistry ns = ...
String uri = ...;
ns.unregisterNamespace(ns.getPrefix(uri));

Comment by anchela [ 16/Jun/11 ]

> however, IMO we can't change the spec of said method without compromising backwards compatibility.

agreed, that's why i asked for clarification...

but we could introduce

  • unregisterByURI(String uri)

and deprecate the old method.

> AFAIU the prefix to be passed to unregisterNamespace(String prefix) refers
> to the current session's prefix<->uri mappings

I am not sure if this is how it is implemented in jackrabbit-core:
There the Workspace#getNamespaceRegistry returns the registry defined on the
RepositoryContext and I doubt that one is aware of any Session
specific namespace remappings.

In any case we should clarify whether the 'prefix' used to unregister a
Namespace is expected to be the one stored in the registry or the one
used currently in the session.

Comment by stefan_guggisberg [ 16/Jun/11 ]

>> AFAIU the prefix to be passed to unregisterNamespace(String prefix) refers
>> to the current session's prefix<->uri mappings
>
> I am not sure if this is how it is implemented in jackrabbit-core:
> There the Workspace#getNamespaceRegistry returns the registry defined on the
> RepositoryContext and I doubt that one is aware of any Session
> specific namespace remappings.

you're right. i forgot about that.

>
> In any case we should clarify whether the 'prefix' used to unregister a
> Namespace is expected to be the one stored in the registry or the one
> used currently in the session.

agreed, it needs clarifying. i guess it should be the former (i.e. the global,
not the session-scoped mapping).

OTOH i don't think that we need to introduce a new method since there's the
trivial workaround:

NamespaceRegistry nsReg = session.getWorkspace().getNamespaceRegistry();
String uri = ...;

nsReg.unregisterNamespace(nsReg.getPrefix(uri));

Comment by rhauch [ 16/Jun/11 ]

I agree with Stefan that we do not need another method.

However, it does seem possible to change (or rather expand) the semantics of the existing method try to match the supplied parameter against both prefix and URI. In order to maintain backward compatibility, the method would first try to match the supplied parameter as a prefix; if one is found, that namespace is unregistered. If no such prefix is found, the implementation could find a namespace with a URI that matches the parameter, and if found unregister that namespace. Obviously the proper session/workspace registry scope would have to be used (perhaps this needs to be clarified in the spec and JavaDoc).

There are several advantages of this change:

  1. only one method is needed, but it serves both purposes
  2. the existing method's name does not denote unregistering only by prefix (this is likely the cause of any misuse, though this becomes an advantage).
  3. the JSR-170 and -283 behavior is still supported and takes precedence, handling any (very unlikely) scenario where URIs are used as prefixes
  4. implementation is straightforward, as it can internally use the workaround that Stefan suggested to implement the lookup of the prefix given the URI
Comment by Peeter Piegaze [ 30/Jun/11 ]

Since one of the official aims of JCR 2.1 is to improve usability, I think it is ok to add improved versions of existing methods (and deprecate old awkward ones).

So, I have deprecated the old unregisterNamespace and added the new method as follows:

/**

  • Removes the specified namespace URI from namespace registry.
    *
  • @param uri The URI to be removed.
  • @throws NamespaceException if an attempt is made to unregister a built-in
  • namespace or a namespace that is not currently registered or a namespace
  • whose unregistration is forbidden for implementation-specific reasons.
  • @throws UnsupportedRepositoryOperationException
  • if this repository does
  • not support namespace registry changes.
  • @throws AccessDeniedException if the current session does not have
  • sufficient access to unregister the namespace.
  • @throws RepositoryException if another error occurs.
  • @since JCR 2.1
    */
    public void unregisterNamespaceByURI(String uri) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException;




[JSR_333-37] Copyright notices and license need update Created: 15/Jun/11  Updated: 28/Jun/11  Resolved: 28/Jun/11

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The copyright notices in the code and the license in the spec and in the txt doc all need to be updated to reflect new dates and the change from Day to Adobe.



 Comments   
Comment by Peeter Piegaze [ 28/Jun/11 ]

copyright notices in java source changed to Adobe
License in spec changed from Day to Adobe
Reference to Sun oin license changed to Oracle
reference to URLs in spec mentioning java.sun.com changed to oracle in those cases where the URL redirects to an orcale URL, otherwise kep the original sun.com address.





[JSR_333-38] Add a getNodes() method to the API Created: 16/Jun/11  Updated: 20/Jun/11  Resolved: 20/Jun/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: lsmith77 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Right now there is only a getNode() method defined in the API, however there are use cases where it would be more efficient to be able to get multiple nodes at once, especially when using a remote API.

For example:

  • fetching the nodes associated with a result set from a search (actually it might be nice to also add some API to request nodes to be returned instead of lucene data in a search)
  • fetching multiple nodes who's paths/uuid are stored in a separate system (f.e. a list of nodes assembled in a browser interface on which certain operations should be executed, like a shopping cart)


 Comments   
Comment by Peeter Piegaze [ 16/Jun/11 ]

What do you mean? Node.getNodes and QueryResult.getNodes are already defined in the API.

Comment by lsmith77 [ 16/Jun/11 ]

yes sorry .. i forgot about QueryResult.getNodes, though the implementation in Jackrabbit for example isnt ideal since it only gives you an iterator which then still requires getting one node at a time.

at any rate I was talking about adding a Session.getNodes

Comment by Peeter Piegaze [ 16/Jun/11 ]

How would Session.getNodes work? Could you give some more details? What kind of object would it return?

Comment by Christian Stocker [ 16/Jun/11 ]

My proposed API for that is:

NodeIterator Session.getNodes(String[] absPath)

this would be in line with the other getNodes definitions

Comment by Peeter Piegaze [ 17/Jun/11 ]

Ok, I understand. That makes some sense. I can imagine that passing a set of paths at once might be advantageous in certain implementations. So +1 to that.

I will add the method as long as no one objects.

Comment by Peeter Piegaze [ 17/Jun/11 ]

Would it also make sense to add

PropertyIterator Session.getProperties(String[] paths) ?

Comment by Peeter Piegaze [ 17/Jun/11 ]

Proposal:
Add the following two methods:
(Note that the the returned nodes and properties are filtered by access control, with no exception thrown in cases of denied access. I thought this would be more natural that throwing if one path among many was denied.)

/**

  • Returns an iterator over all the nodes at the specified absolute paths
  • in the workspace that exist and are accessible to this session.
  • If none of the specified paths leads to an existing and accessible
  • node then an empty iterator is returned.
    *
  • @param absPaths An array of absolute paths.
  • @return an iterator over all nodes that exist at the specified paths and that are accessible.
  • @throws RepositoryException If an error occurs.
  • @since JCR 2.1
    */
    public Node getNodes(String[] absPaths) throws RepositoryException;

/**

  • Returns an iterator over all the properties at the specified absolute paths
  • in the workspace that exist and are accessible to this session.
  • If none of the specified paths leads to an existing and accessible
  • property then an empty iterator is returned.
    *
  • @param absPaths An array of absolute paths.
  • @return an iterator over all properties that exist at the specified paths and that are accessible.
  • @throws RepositoryException If an error occurs.
  • @since JCR 2.1
    */
    public Node getProperties(String[] absPaths) throws RepositoryException;
Comment by Peeter Piegaze [ 17/Jun/11 ]

Sorry, obviously those methods should return iterators:

public NodeIterator getNodes(String[] absPaths) throws RepositoryException;
public PropertyIterator getProperties(String[] absPaths) throws RepositoryException;

Comment by lsmith77 [ 17/Jun/11 ]

just to make sure we are on the same page (which sounds like it from the above API):
missing nodes (properties) should also not throw an error.

Comment by Peeter Piegaze [ 17/Jun/11 ]

> just to make sure we are on the same page (which sounds like it from the above API):
> missing nodes (properties) should also not throw an error.

Agreed. That is what I mean when I say that the retrurned nodes/properties are filtered...and might even be filtered to the point where the iterator is empty, in the extreme case where none of the paths given are existant/accessible

Comment by Peeter Piegaze [ 20/Jun/11 ]

Added getNodes and getProperties as described above.





[JSR_333-15] Define access control for repository level operations Created: 12/Oct/10  Updated: 15/Jun/11  Resolved: 15/Jun/11

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: anchela Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Attachments: Microsoft Word jcr-spec-acm-proposed-changes.doc     Microsoft Word jcr-spec-acm-proposed-changes_comment_angela.doc    
Issuezilla Id: 15

 Description   

currently the specification doesn't define how access control on repository
level operations

  • namespace registr.
  • node type registr.
  • workspace mgt

should be handled.



 Comments   
Comment by anchela [ 12/Oct/10 ]

this is a follow up for https://jsr-283.dev.java.net/issues/show_bug.cgi?id=486
for those parts that have been left to the implementation.

Comment by Peeter Piegaze [ 12/Jan/11 ]

Changed platform to "All"

Comment by Peeter Piegaze [ 24/Mar/11 ]

The current spec defines the following privileges:

jcr:all
jcr:read
jcr:readAccessControl
jcr:modifyAccessControl
jcr:lockManagement
jcr:versionManagement
jcr:nodeTypeManagement
jcr:retentionManagement
jcr:lifecycleManagement
jcr:write
jcr:modifyProperties
jcr:addChildNodes
jcr:removeNode
jcr:removeChildNodes

jcr:all is an aggregate privilege that includes all other privileges.
jcr:write is an aggregate privilege that includes the four more specific write privileges

This issue proposes to add three additional privileges:

jcr:workspaceManagement: covers the ability to create and remove workspaces in the repository.

jcr:nodeTypeDefinitionManagement: covers the ability to register, unregister and change the definitions of node type in the repository.

jcr:namespaceManagement: covers the ability to register, unregister and modify namespace definitions.

Unlike the current privileges, these three are not associated with any particular node. Since the existing
AccessControlManager methods for checking privileges all take an absPath, a solution has to be found for how
these methods work with the three new privileges. The methods in question are:

Privilege[] getSupportedPrivileges(String absPath)
boolean hasPrivileges(String absPath, Privilege[] privileges)
Privilege[] getPrivileges(String absPath)

Here are some proposals on how to handle the new privileges using the existing methods:

1) Each of the three new privileges either applies to all nodes in a workspace or to no nodes in a workspace. In other words the absPath becomes irrelevant when dealing with these privileges.

2) The three new privileges are considered to apply to the "null" absPath. So, for example, in a system that supports all three of the new privileges, a call to

acm.getSupportedPrivileges(null);

would return:

{jcr:workspaceManagement, jcr:nodeTypeDefinitionManagement, jcr:namespaceManagement}

Passing a null to hasPrivileges or getPrivileges would work similarly.

3) Introduce new methods to deal with these new privileges

Comment by anchela [ 31/Mar/11 ]

A) privilege names
-> fine by me

B) privilege discovery
-> not sure... having new methods feels odd... so 2) is currently
my preferred though not loved solution... if we went for 2) we
had to adjust the wording that always states that the path
defines an existing node.
-> or should they be supported on the root node only? see (C)

C) access control editing
may be we should take a look at this as well... i guess that finding
a solution for the editing could help us solving the discovery issue (B).
in other words: how would one grant workspacemanagement privilege to
somebody.
if we went for acm.getSupportedPrivileges(null) there was also the
need to retrieve applicable policies etc. with a 'null' path argument.
furthermore: would those repo-level privileges be the same for
each workspace as the effect is not limited to a single workspace?

D) define what is a privilege:
currently the API states

"A privilege represents the capability of performing a particular set
of operations on items in the JCR repository"

if we introduce privileges for repository level operations this
isn't true any more.

Comment by Peeter Piegaze [ 12/Apr/11 ]

> 2) is currently my preferred though not loved solution...
> if we went for 2) we had to adjust the wording that always
> states that the path defines an existing node.

Using null as the path argument seems the most logical solution. And we would have to adjust the wording about the path argument always pointing to a node.

> or should they be supported on the root node only? see (C)

I think for repo-wide settings null is better. These particular privileges have no meaning (I think) in a workspace-wide context (i.e., they only apply repo-wide) so in the case of these particular privileges using the root node might be ok. However, since the set of privileges is supposed to be extensible by implementations, there may be other privileges (that we do not define) which have differing effect repo-wide vs. ws-wide. So, for this reason I think we must distinguish repo from WS using null vs "/"

> if we went for acm.getSupportedPrivileges(null) there was also the
> need to retrieve applicable policies etc. with a 'null' path argument.

Yes. the use of the null path as meaning "repo-wide" would also apply to getting, setting and removing policies.

> furthermore: would those repo-level privileges be the same for
> each workspace as the effect is not limited to a single workspace?

Technically this would be implementation detail of the policy itself. In theory the node to which a policy
is bound is already not necessarily connected directly to the effect of the policy. See 16.3.5 (and associated footnote) which I have copied below:

16.3.5 Scope of a Policy
...
When an access control policy takes effect, it may affect the accessibility characteristics not only of the node to which it is bound but also of nodes elsewhere in the workspace[20].

[20] One common case is a policy that affects both its bound node and the subgraph below that node. However, any such deepness attribute is internal to the policy and, like any other internal characteristic of a policy, opaque to the JCR API except insofar as it is part of the human-readable name and description. Note also that, strictly speaking, a policy is not required to affect even its bound node, though such an implementation would be uncommon.

Comment by Peeter Piegaze [ 04/May/11 ]

Proposal for resolving this issue: A Word doc with track changes.

Comment by Peeter Piegaze [ 04/May/11 ]

I have attached a proposal for this issue. It is change tracke Word doc.

Please review and comment.

http://java.net/jira/secure/attachment/45723/jcr-spec-acm-proposed-changes.doc

Comment by anchela [ 14/Jun/11 ]

attached a commented version of the diff.

there is one thing that i felt uneasy with: the statement that the user is a session.
from my point of view this isn't correct (see attachement for wordy explanation).

i think we should stick with the notion that privileges are assigned to a principal
for a given object (was: node). how this is matched to a given session is up to now
left to the implementation and i would rather not want to introduce something like
'user' as this seems really confusing to me (see also AccessControlList).

Comment by Peeter Piegaze [ 15/Jun/11 ]

My changes plus Angela's adjustments have been made.





[JSR_333-31] Clean up PHPCR section of spec document Created: 10/Jun/11  Updated: 15/Jun/11  Resolved: 15/Jun/11

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The PHPCR section needs a bit of cleanup to bring it inline with the style of the ret of the document.



 Comments   
Comment by Peeter Piegaze [ 15/Jun/11 ]

PHPCR section cleaned up to reflect style of spec document. Some minor questions remain, highlighted within the text.





[JSR_333-28] Define an API for PHP (aka PHPCR) Created: 07/Apr/11  Updated: 10/Jun/11  Resolved: 10/Jun/11

Status: Resolved
Project: jsr-333
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Christian Stocker Assignee: Unassigned
Resolution: Fixed Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

While JCR was specifically written for Java in mind, initiatives were started to port the API to other languages, specifically in this case PHP. There's the project Jackalope (http://jackalope.github.com/) which implements a "Jackrabbit" client in PHP (using the webdav protocol). Jackalope uses the PHPCR interfaces, which were originally created by the Typo3/Flow3 team and were slightly adopted to some PHP specifics, but directly derived from the JSR-283 specs (https://github.com/phpcr/phpcr, the changes are described here https://github.com/phpcr/phpcr/blob/master/doc/JCR_TO_PHPCR.txt). And just lately the midgard project also started with using the PHPCR interfaces (https://github.com/bergie/phpcr-midgard2)

We'd like now to propose making PHPCR more official and to include it in the next release of the JCR specs, so that there is an agreed "standard" and also that we can solve some legal issues (regarding derived work of the original JCR specs)



 Comments   
Comment by lsmith77 [ 07/Apr/11 ]

The popular Symfony PHP framework is using PHPCR for their CMF initiative: http://cmf.symfony.com/
To ease development we have also created an ODM (object document model) layer using the popular Doctrine2 (sort of a Hibernate for PHP): https://github.com/doctrine/phpcr-odm

In other words there is considerable commitment behind PHPCR already. The goal is to formalize this especially to ensure that different implementations like Jackalope and Midgard will play nicely with eachother, but also to ensure that PHPCR and JCR stay compatible.

In a second step we might also want to look at adding some things into JCR that scripting languages in general would appreciate (for example native support for associative arrays).

Comment by dbu [ 08/Apr/11 ]

note that we are currently in the process of separating the phpcr interfaces from the jackalope implementation to make it more obvious what is the standard. https://github.com/jackalope/phpcr will become https://github.com/phpcr/phpcr

Comment by Peeter Piegaze [ 12/Apr/11 ]

What would be the most logical first step? Presumably we would want to include the source and auto-generated docs in the package just as we now include the java source and javadoc. But in terms of adapting the spec itself, would it be sufficient to include a new section containing, essentially, the information in https://github.com/phpcr/phpcr/blob/master/doc/JCR_TO_PHPCR.txt or would we need to change more of the spec?

Comment by Christian Stocker [ 12/Apr/11 ]

Yes, I think this would be a sensible approach. Provide the interfaces with source and auto-generated docs. And explain the differences and common conversions from the Java-interfaces in a chapter in the specs.
Once the JSR-333 java interfaces are "ready", we adopt the current PHPCR interfaces and go through all the methods and document the differences (like eg. all the overloaded methods we merged into one)

I guess it would be good, if we document all changes in the doc, but I guess it doesn't end up in much more than is already in the JCR_TO_PHPCR.txt doc

Comment by dbu [ 15/Apr/11 ]

yes, JCR_TO_PHPCR is more or less complete. there was some stuff added to the phpcr api later, but i think its debatable if it makes any sense to have that there (we could also make it impl specific)

what really needs a good final decision is binary handling. we half-use the BinaryInterface and should decide what we really want (with respect to performance and future proof).

Comment by Peeter Piegaze [ 10/Jun/11 ]

The PHPCR code has been added to svn, and the PHPCR section has been added to the spec.
The section needs a bit of clean up and may change as features are aded to PHPCR. But, I'm going to close this issue and add separate issues for cleanup and locking etc.





[JSR_333-27] Session.impersonate: unclear if cloning a session is allowed Created: 25/Mar/11  Updated: 10/May/11  Resolved: 10/May/11

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: thomasmueller2 Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The Javadoc documentation of Session.impersonate says: "Allows the current user to impersonate another...". Could this be changed to "Allows the current user to impersonate a user..." or "another or the same user..."?

I currently use this method to clone a session ('impersonate myself') using:

session.impersonate(new SimpleCredentials(session.getUserID(), "".toCharArray()));

Of course it's a somewhat sneaky way to clone a session, but there is no other API (there is no session.clone). Of course, instead of cloning a session, I could open a new session, but in that case I would have to keep the credentials, which is a security problem (I would like to clear the password field).

I don't immediately see a reason why impersonating myself should be disallowed in general, if the session has the required access rights. Technically, its already possible to define two users that can impersonate each other.



 Comments   
Comment by thomasmueller2 [ 25/Mar/11 ]

I forgot to say: an alternative is to add a Session.clone() method, but I don't think the use case is important enough for a new method. My use case is:

a) A JCR session is assigned to the web session after a successful login.

b) The web application has a timeout of 30 minutes (which is required to avoid out of memory), so the original JCR session is closed after 30 minutes of inactivity (which is good).

c) Some operations potentially take longer than 30 minutes, or should be run on a different session because sharing a session for distinct operations is quite problematic.

d) For those operations, I would like to use a new session, but don't want that the user has to login again (that would be a usability problem) and I don't want to keep the password in the web application (which would be a security problem; the password in SimpleCredentials is a character array and not a String specially so that that the password can be cleared and doesn't stay in memory until garbage collected).

e) Therefore, I would like to clone the existing session (create a additional, new session with the exact same user and access rights).

Comment by Peeter Piegaze [ 09/May/11 ]

I propose we simply change the wording to allow "self-impersonation"

Comment by Peeter Piegaze [ 10/May/11 ]

Spec and source updated to clarify that session cloning through impersonate is permitted.





[JSR_333-13] Repository Lifecycle Management Created: 26/Sep/10  Updated: 31/Mar/11  Resolved: 31/Mar/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: uncled Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 13

 Description   

janne.jalkanen@ecyrd.com proposes in an email:


[...]
Repository lifecycle management would be useful - if apps are embedding JCR containers, there's no clear
way to for example tell them to reload the configuration or restart (or even shutdown cleanly). I know it's
useless if you're connecting elsewhere, but it would be nice to be at least to hint. For example through a
RepositoryManagement interface or a set of standard JMX calls...
[...]



 Comments   
Comment by uncled [ 26/Sep/10 ]

changing component

Comment by Peeter Piegaze [ 22/Mar/11 ]

The originator of this issue, Janne Jalkanen proposes the following:

public interface EmbeddedRepository extends Repository

{ /** Causes the Repository to reload its configuration. */ public void reload() throws RepositoryException; /** Performs a shutdown of the repository. Any subsequent calls to any Repository methods throw an exception. */ public void shutdown() throws RepositoryException; }

public class RepositoryManager

{ /** Returns a default repository. It's implementation-specific as to what kind of a default repository you get, but authors should make sure it's usable. */ public static EmbeddedRepository getRepository(); /** Returns a repository using the specified configuration. The exact form of the configuration is dependent on the repository type. */ public static EmbeddedRepository getRepository(InputStream configuration); }
Comment by rhauch [ 22/Mar/11 ]

A few comments.

1) Might we consider using this form for the shutdown method, which work with an implementation that shut down synchronously or asynchronously, and would allow the caller to optionally wait for the shutdown to occur:

/**

  • Performs a shutdown of the repository. This method will block at most the supplied time while the repository shuts down.
  • Any subsequent calls to any Repository methods throw an exception.
  • @param timeout the maximum time to wait for each component in this engine
  • @param unit the time unit of the timeout argument
    */
    public void shutdown( long time, TimeUnit unit ) throws RepositoryException, InterruptedException;

2) I dislike how the RepositoryManager class is essentially enforcing a singleton EmbeddedRepository instance (via the single static getter). This will not allow an application to embed multiple repositories. What's the behavior if getRepository(InputStream) is called more than once (where the streams contain different configurations)? Also, how will the static methods on the RepositoryManager class be implemented, such that the exact behavior is implementation-specific. Does it just use the ServiceLoader/RepositoryFactory pattern outlined in JSR-283, and check the type of the returned Repository for instanceof EmbeddedRepository? Finally, why is "RepositoryManager" really restricted to managing a EmbeddedRepository instance, rather than just any Repository instance?

3) The "getRepository(...)" method of RepositoryManager (in whatever form it takes) should ideally be compatible with this existing RepositoryFactory method:

/**

  • Attempts to return the embedded repository identified with the given
  • <code>parameters</code>. <p> Parameters are passed in a <code>Map</code>
  • of <code>String</code> key/value pairs, and can be the same properties
  • passed to RepositoryFactory.getRepository(Map). The keys are not specified by JCR
  • and are implementation specific. However, vendors should use keys that
  • are namespace qualified in the Java package style to distinguish their
  • key names. For example an address parameter might be
  • <code>com.vendor.address</code>. <p> The implementation must return
  • <code>null</code> if it does not understand the given parameters. The
  • implementation may also return <code>null</code> if a default repository
  • instance is requested (indicated by <code>null</code>
  • <code>parameters</code>) and this factory is not able to identify a
  • default repository. <p> An implementation of this method must be
  • thread-safe.
    *
  • @param parameters map of string key/value pairs as repository arguments
  • or <code>null</code> if none are provided and a client wishes to connect
  • to a default repository.
  • @return a repository instance or <code>null</code> if this implementation
  • does not understand the passed <code>parameters</code>.
  • @throws RepositoryException if if no suitable repository is found or
  • another error occurs.
    */
    public Repository getRepository(Map parameters) throws RepositoryException;
Comment by rhauch [ 22/Mar/11 ]

Rather than just shooting down the proposal, I thought I should provide one alternative. I liked the originator's initial idea of having a separate RepositoryManager interface, which I might define as:

public interface RepositoryManager

{ void reload() throws RepositoryException; void shutdown( long time, TimeUnit unit) throws RepositoryException; /* Repository that this instance manages. * (Since Repository instances don't have identifiers, this is really the only way to expose this information.) */ Repository getRepository(); }

This would separate the management concerns from the typical client usage of Repository, and would mean there's an instance that represents the management hook. In fact, an implementation is actually able (but not required) to have a Repository implementation class also implement RepositoryManager.

What if an instance of this interface could be returned by a new method in the RepositoryFactory interface:

public interface RepositoryFactory

{ /* existing method */ Repository getRepository(Map parameters) throws RepositoryException; /* Return an object that can be used to manage the repository. */ RepositoryManager getRepositoryManager(Repository) throws AccessDeniedException, RepositoryException; }

This approach does not use static methods, does not preclude having more than one repository, and is tied in more closely with how the existing RepositoryFactory interface works. I'm not convinced that RepositoryFactory is the place to have this new method, but that interface is there, works with ServiceLoader, and IMO it's important that the mechanism be compatible with how RepositoryFactory already works.

It may also be possible to have the 'getRepositoryManager' method take the same Map parameters as 'getRepository'. If the RepositoryFactory implementation required a Repository instance, couldn't it just call it with the same Map parameters? I decided not to go this route simply because that might not be feasible for some implementations that always create new Repository instances for a given set of Map parameters.

Comment by stefan_guggisberg [ 24/Mar/11 ]

comments regarding the original proposal by janne jalkanen:

  • RepositoryManager is not a valid java class; apart from that,
    we should stay away from adding concrete java classes to the JCR api.
  • shutdown() should IMO not be exposed on the Repository interface

comments regarding randal's revised proposal:

  • while it addresses most of my concerns regarding the original
    proposal, i do question the value of the reload and shutdown methods.
    the behavior of the reload method is implementation specific,
    i fail to see how a generic client would benefit from exposing such a method.

IMO a client should never have to call the shutdown method.

BTW, AFAIK there's no comparable methods on the JDBC api, i take that as a hint...

Comment by rhauch [ 24/Mar/11 ]

I, too, am not sure of the value of 'reload()', but I do see the value in shutting down a repository. Some repository implementations have resources (e.g., thread pools, connection pools) that should be cleaned up only when the repository is no longer needed/wanted. This doesn't always correspond to when all local sessions have been closed.

There are two primary scenarios where a method at the JCR API level is useful:
1) In clustering cases, client applications may want to keep the repository active (to maintain participation in the cluster) regardless of whether all local sessions have terminated.
2) When an embedding application has been asked to terminate and require that all existing/open sessions be forced to close while also preventing the creation of new sessions.

Obviously not all implementations may have a need for explicit shutdown (perhaps they always release all resources when the last session has closed). And even if they are not clusterable, I still think that the second scenario is valid and applicable. Note that the JCR reference implementation (Jackrabbit) already does have a 'shutdown()' method on the TransientRepository that seems to fit with scenario #2; see http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/core/TransientRepository.html#shutdown()

There definitely is precedent within the JDK and other libraries for components that do have an explicit lifecycle. The java.util.concurrent package has quite a few classes that have such methods. Also, JDBC does not need such a method because it is merely a client connecting to a remote resource (that does have a lifecycle).

I've thought more about my proposal, and I neglected to account for authorization. Since no credentials are required to obtain a Repository instance, there really was no way to supply credentials for getting a RepositoryManager. One way to address this is to instead put the 'getRepositoryManager()' method inside the Workspace interface. Getting a Workspace instance requires an authenticated Session, and the Workspace implementation can use its authorization mechanism to determine whether the RepositoryManager should be returned (if that's the semantics we'd like to have) or to make the RepositoryManager instance unique to the Workspace so it can also use the same authorization mechanism for its methods.

One downside of this alternative is that since the RepositoryManager is in the scope of an open Session, we'd have to define the semantics of what happens when 'shutdown()' are called re open sessions. For example, should any open sessions be closed immediately (including sessions used for event listeners and the session used to shut down the repository)? Should that be a parameter?

I'll amend my earlier proposal to take this into account and to follow the pattern for shutdown and awaitTermination methods used by classes within the JDK (e.g., ExecutorService). My amended and roughly-JavaDoc-ed proposal would then be this:

public interface RepositoryManager {

/**

  • Initiates an orderly shutdown of the Repository, preventing the creation of new sessions while
  • allowing existing sessions to be used. The shutdown will complete only after all existing sessions
  • obtained prior to this call are closed.
  • <p>
  • This method does not wait for the shutdown process to complete; for that,
  • see {@link #awaitTermination(long,java.util.concurrent.TimeUnit)}.
    * </p>
    * @throws AccessDeniedException if the caller does not have authorization to shut down the repository
    * @throws RepositoryException if an error occurred while shutting down the repository
    */
    void shutdown()
    throws AccessDeniedException, RepositoryException;

    /**
    * Attempts to shutdown the repository immediately by preventing the creation of new sessions
    * and closing all existing sessions. an orderly shutdown of the Repository, preventing the creation of new sessions while
    * allowing existing sessions to be used. The shutdown will complete only after all existing sessions
    * obtained prior to this call are closed.
    * <p>
    * This method does not wait for the shutdown process to complete; for that,
    * see {@link #awaitTermination(long,java.util.concurrent.TimeUnit)}

    .

  • </p>
  • @throws AccessDeniedException if the caller does not have authorization to shut down the repository
  • @throws RepositoryException if an error occurred while shutting down the repository
    */
    void shutdownNow()
    throws AccessDeniedException, RepositoryException;
    /**
  • Blocks until the shutdown process has completed, or the timeout occurs, or the current thread is interrupted,
  • whichever happens first. This method returns immediately if a shutdown has not been initiated.
  • @param timeout the maximum time to wait
  • @param unit the time unit of the timeout argument
  • @return true if the repository terminated, or false if the timeout elapsed before termination
  • @throws InterruptedException if interrupted while waiting
    */
    boolean awaitTermination( long timeout, TimeUnit unit) throws InterruptedException;
    }

public interface Workspace

{ ... /** * Return a RepositoryManager that can be used to administer the Repository instance through * which this workspace's session was acquired. * @return the repository manager; never null * @throws AccessDeniedException if the caller does not have authorization to obtain the manager * @throws RepositoryException if another error occurred */ RepositoryManager getRepositoryManager() throws AccessDeniedException, RepositoryException; ... }
Comment by rhauch [ 24/Mar/11 ]

BTW, I've personally spoken with several developers of open source projects that are designed to work with multiple JCR repository implementations, and they all have had to implement a way to find a Repository instance and to shut them down. Luckily, the addition of RepositoryFactory in JCR 2.0 provided a standard way to find (and start) a Repository, but there currently is no standard way to shut one down.

Comment by stefan_guggisberg [ 25/Mar/11 ]

> Also, JDBC does not need such a method because it is merely a client connecting to a remote resource (that does have a lifecycle).

well, not quite. there are several embedded databases (e.g. derby, hsqldb, to name a few). JDBC and JCR are IMO
indeed comparable as they're both 'client' APIs, connecting to a remote, local or embedded database/repository.
AFAIK there's no 'standard' way of shutting down an embedded database instance...

i don't question the usefulness of a 'shutdown()' method in general, but exposing a 'shutdown()' method on a standardized
client API IMO does feel wrong. imagine two applications unknowingly sharing the same embedded repository instance. what
happens if one application decides to shutdown the repository because it doesn't need it anymore?

anyway, in case i am the only one having these concerns, i'd be happy to accept being voted down.

Comment by thomasmueller2 [ 25/Mar/11 ]

A few remarks:

> there's no 'standard' way of shutting down an embedded database instance

That's true. As for embedded Java databases: HSQLDB and H2 support the 'SHUTDOWN' statement. For Apache Derby, to close a database, you need to open a new connection but append ;shutdown=true to the database URL (which is weird in my view).

A relatively clean solution is 'the last one closes the door' (automatically close the repository / database when all sessions / connections are closed). This is supported by the Jackrabbit TransientRepository, and by the H2 database (here with the option to specify a 'close delay'). There are two main usability problems: The application has to 'know' all sessions / connections (keep a list) which is sometimes not easy (the JCR Session.impersonate can open a new session). The second problem is if an application quickly opens and closes a single session. In that case, the database / repository is opened and closed a lot, which is potentially quite slow. For JDBC, the workaround is to use a connection (connection pools have a 'dispose' method).

awaitTermination: in my view, this isn't an important feature, as I don't know a similar feature in other APIs. More generic would be a 'session / repository event listener' that would be notified about new sessions / closed sessions / when the repository is closed. In theory, you could use regular JCR observation for this (if each session is a node in the repository, probably within jcr:system), therefore no new API is required.

Comment by Peeter Piegaze [ 28/Mar/11 ]

Thomas, would you object to including shutdown and shutdownNow, but excluding awaitTermination?

rhauch, would you object to that?

Comment by thomasmueller2 [ 29/Mar/11 ]

I would rather not add Repository.shutdown() and shutdownNow(). I think we need to find a better solution, and if we can't, we shouldn't add such a feature at all, and suggest to use 'the last one closes the door' instead.

About access rights: even with an embedded repository, we might want to restrict closing the repository. I don't see how this could be done with a simple 'shutdown()' method. For HSQLDB and H2, the 'SHUTDOWN' statement is ran from a connection, so if the JCR API would like to support something similar, it would have to be Session.shutdownRepository() or Repository.shutdown(Credentials c) or something like this.

By the way, Jackrabbit does support closing a repository, but the API is relatively complicated:

interface JackrabbitRepositoryFactory extends RepositoryFactory

{ org.apache.jackrabbit.api.management.RepositoryManager getRepositoryManager(org.apache.jackrabbit.api.JackrabbitRepository rep) }

interface org.apache.jackrabbit.api.management.RepositoryManager

{ void stop(); DataStoreGarbageCollector createDataStoreGarbageCollector(); }

The idea is that the owner of the RepositoryFactory is allowed to close the repository, because there is no way to navigate to the RepositoryFactory from a 'low level' object such as a Node. I'm not sure if that's really a correct assumption.

What do others think?

Comment by rhauch [ 29/Mar/11 ]

My proposal was to add the 'shutdown()' and 'shutdownNow()' methods to a new RepositoryManager interface, not to the existing Repository interface. I completely agree that adding such methods to the Repository interface is bad form and exposes them to all JCR users.

It sounds like Jackrabbit's existing mechanism is similar to my original proposal, which (as I detailed above) is problematic from an authorization perspective. After all, per JSR-283, the only standard and implementation-independent mechanism to obtain a Repository instance is by finding the RepositoryManager instance using the ServiceLoader mechanism, which any component can do. In other words, any component should be able to find the RepositoryFactory. And since the RepositoryFactory is registered with the JRE's ServiceLoader mechanism (via a file in the implementation's JAR file(s), this can't easily be different for embedded vs. non-embedded cases.

Both Jackrabbit and ModeShape have such a mechanism, and maybe other implementations do, too? (Anybody know?)

Thomas, do you think an explicit shutdown mechanism is useful, at least in the embedded case?

Comment by rhauch [ 29/Mar/11 ]

Thomas wrote:

> awaitTermination: in my view, this isn't an important feature, as I don't know a similar feature in other APIs.
> More generic would be a 'session / repository event listener' that would be notified about new sessions / closed
> sessions / when the repository is closed. In theory, you could use regular JCR observation for this (if each session
> is a node in the repository, probably within jcr:system), therefore no new API is required.

I would agree that this is a useful mechanism for notifying sessions that the repository is *going to shutdown*, but it's difficult (if not impossible) to use this mechanism to know when the repository has completed its shutdown. After all, don't the listener's sessions have to be closed before the repository is completely shut down? That's the point of 'awaitTermination':

// Get the repository manager, which may fail if the session doesn't have sufficient
// privileges or the repository is not embedded...
RepositoryManager mgr = session.getWorkspace().getRepositoryManager();

// Begin shutting down the repository. This prevents more sessions from being created,
// but allows existing sessions to be used and closed naturally.
// Alternatively, call 'mgr.shutdownNow()' to prevent more sessions from being created
// AND have existing sessions be closed immediately.
mgr.shutdown();

// Wait for no more than 30 seconds until the repository is completely shutdown ...
try

{ mgr.awaitTermination(30,TimeUnit.SECONDS); }

catch ( InterruptedException e )

{ // handle appropriately }
Comment by thomasmueller2 [ 29/Mar/11 ]

I think a shutdown mechanism is useful.

> RepositoryManager mgr = session.getWorkspace().getRepositoryManager();

That OK in my view, but what about the simpler:

RepositoryManager mgr = session.getRepositoryManager();

which is similar to the already existing session.getAccessControlManager()

> mgr.shutdown();

What about mgr.closeRepository(boolean immediately) instead? mgr.shutdown() sounds like the manager is to be shut down (instead of the repository), and mgr.shutdownRepository() sounds weird.

> mgr.awaitTermination(30,TimeUnit.SECONDS);

I would have assumed that mgr.shutdown() doesn't return until the repository is closed (until all sessions are closed). If you want to close it immediately, you would have to call mgr.closeRepository(true). If you want to wait at most 10 seconds (which isn't an important use case in my view), you could call mgr.closeRepository(false) in a separate thread, wait 10 seconds, and if not closed call mgr.closeRepository(true).

> it's difficult (if not impossible) to use this mechanism to know when the repository has completed its shutdown

What about Repository.isClosed()?

Comment by rhauch [ 29/Mar/11 ]

> I think a shutdown mechanism is useful.
>
> > RepositoryManager mgr = session.getWorkspace().getRepositoryManager();
>
> That OK in my view, but what about the simpler:
>
> RepositoryManager mgr = session.getRepositoryManager();
>
> which is similar to the already existing session.getAccessControlManager()

The only reason I suggested Workspace was that the existing interfaces exposed by Workspace seemed to be more session-independent (e.g., NamespaceRegistry, NodeTypeManager, etc.), while the only two interfaces currently exposed by Session (e.g., AccessControlManager and RetentionManager) are both session-specific.

To me it seems a better fit in Workspace, but I can be convinced.

>
> > mgr.shutdown();
>
> What about mgr.closeRepository(boolean immediately) instead? mgr.shutdown() sounds like the manager
> is to be shut down (instead of the repository), and mgr.shutdownRepository() sounds weird.

Very good point. I agree that 'closeRepository' is a better name. And I'm fine with collapsing the two methods into one by adding the boolean parameter.

>
> > mgr.awaitTermination(30,TimeUnit.SECONDS);
>
> I would have assumed that mgr.shutdown() doesn't return until the repository is closed (until all sessions
> are closed). If you want to close it immediately, you would have to call mgr.closeRepository(true). If you
> want to wait at most 10 seconds (which isn't an important use case in my view), you could call mgr.closeRepository(false)
> in a separate thread, wait 10 seconds, and if not closed call mgr.closeRepository(true).

Unfortunately that logic is not terribly intuitive to most developers, especially because you have to interrupt your spawned thread and therefore run the risk of not properly shutting down the repository.

Perhaps the important decision is whether the closeRepository method blocks. Is it safe to assume that 'closeRepository(false)' would not block? I personally think it's far easier, more flexible, and consistent if 'closeRepository(true') also does not block and, if needed, my app can wait (regardless of the 'immediate' parameter) by simply calling ''awaitRepositoryTermination()'.

BTW, the 'awaitTermination' in ExecutorService was explicitly chosen over 'awaitShutdown' because you're not waiting for the shutdown method to be called.

>
> > it's difficult (if not impossible) to use this mechanism to know when the repository has completed its shutdown
>
> What about Repository.isClosed()?

The problem with this is all users can see it, and do they now have to take this into account in their code? Closing a repository immediately would likely result in exceptions in any thread using an open session, but this is something they already have to handle. Adding this method complicates things a bit.

Comment by thomasmueller2 [ 29/Mar/11 ]

Both session.getWorkspace().getRepositoryManager() and session.getRepositoryManager() are fine for me.

> Repository.isClosed()

OK I see it doesn't fit very well. The JDBC API has Connection.isClosed() and Connection.isValid(), but a connection isn't a repository.

Personally, I think that both mgr.closeRepository(false) and mgr.closeRepository(true) should block, which simplifies the (in my view) most common cases... I do understand you would like some kind of 'wait' mechanism but I think that's not necessary because it's not a very common use case (again, in my view). awaitTermination more sounds like a convenience method to me than something that is really, really needed by many users. And, it's possible to work around it: the repository is closed when the mgr.closeRepository call returns normally (calling it multiple times shouldn't throw an exception I guess). And if mgr.closeRepository(false) doesn't return in a reasonable time, you could call mgr.closeRepository(true) in another thread.

Just an idea: mgr.closeRepository(int maxWaitSeconds) - it would return normally if the repository was closed within the specified time (1 second, 10 seconds,...); would throw a timeout exception if not, and (as a special case) with maxWaitSeconds = 0 it would force closing (close all existing sessions). But maybe that would be too much magic already.

Comment by thomasmueller2 [ 29/Mar/11 ]

To clarify: I think mgr.closeRepository(boolean immediately) should only return normally when the repository was actually closed. I think it would be really weird if the method returns normally but the repository is still open.

If you do think asynchronous closing is important (which I believe it not), then the method name should be different, for example boolean mgr.tryCloseRepository(boolean immediately) - similar to java.util.concurrent.lock.Lock: boolean tryLock(long time, TimeUnit unit).

Comment by rhauch [ 29/Mar/11 ]

I think we've met in the middle. Here's my understanding of what we've settled upon, and please correct me if I'm mistaken. The first is the new 'RepositoryManager' interface:

/**

  • A <code>RepositoryManager</code> object represents a management view of the Session's Repository instance.
  • This is useful for applications that embed a JCR repository and need a way to manage the lifecycle of that
  • Repository instance. Each <code>RepositoryManager</code> object is associated one-to-one with a
  • <code>Session</code> object and is defined by the authorization settings of that session object.
  • <p>
  • The <code>RepositoryManager</code> object can be acquired using a {@link Session}

    by calling

  • <code>Session.getWorkspace().getRepositoryManager()</code> on a session object, and the
  • Likewise, the Repository being managed can be found for a given RepositoryManager object by calling
  • <code>mgr.getWorkspace().getSession().getRepository()</code>.
  • </p>
  • @since 2.1
    */
    public interface RepositoryManager {
    /**
  • Return the <code>Workspace</code> object through which this repository manager was created.
  • @return the {@ Workspace}

    object.
    */
    Workspace getWorkspace();

/**

  • Closes the <code>Repository</code> by preventing the creation of new sessions
  • and freeing all resources. The <code>immediate</code> parameter dictates whether existing
  • sessions should be closed immediately or allowed to close naturally.
  • Either way, this method always blocks until all sessions are closed and the repository has
  • completely terminated.
  • <p>
  • Some repository implementations may not allow repositories to be closed, while other
  • implementations might allow closing only for certain configurations (e.g., repositories
  • embedded within an application). An implementation will throw an
  • {@link UnsupportedRepositoryException}

    if the particular repository cannot be closed,

  • or an {@link AccessDeniedException}

    when the repository can be closed but the session does

  • not have the authority to do so.
  • </p>
  • @param closeSessionsImmediately true if all existing sessions should be closed immediately,
  • or false if they are to be allowed to close naturally.
  • @throws AccessDeniedException if the caller does not have authorization to close the repository.
  • @throws UnsupportedRepositoryException if the repository implementation does not support
  • or allow the repository to be closed.
  • @throws RepositoryException if an error occurred while shutting down the repository.
    */
    void closeRepository( boolean closeSessionsImmediately )
    throws AccessDeniedException, UnsupportedRepositoryException, RepositoryException;
    }

And to the existing "Workspace" interface we add the following method to return a RepositoryManager instance:

public interface Workspace {
...

/**

  • Return a RepositoryManager that can be used to administer the Repository instance through
  • which this workspace's session was acquired.
  • @return the {@link RepositoryManager}

    instance.

  • @throws AccessDeniedException if the caller does not have authorization to obtain the manager.
  • @throws RepositoryException if another error occurred.
  • @since 2.1
    */
    RepositoryManager getRepositoryManager()
    throws AccessDeniedException, RepositoryException;

...
}

As much as I'd think there should be a "RepositoryManager.getRepository()" method, that's not the pattern of the JSR-283 interfaces. I think it's more important to be consistent, so I left such a method out of the proposal.

Comment by Peeter Piegaze [ 29/Mar/11 ]

Stefan, what do you think of this latest proposal?

Comment by stefan_guggisberg [ 30/Mar/11 ]

i'm fine with randall's latest proposal. i have one minor suggestion however,
i think we should add language that implementations may not support/allow
closing the repository method for various reasons. maybe we should
explicitly add UnsupportedRepositoryException to the throws clause.

Comment by rhauch [ 30/Mar/11 ]

I agree with Stefan's suggestion on the language to add, and am good with adding the exception to the throws clause for 'closeRepository()'. I've update the proposed code above, but I'd be happy to hear of alternative suggestions for any of the wording in the JavaDoc.

Comment by Peeter Piegaze [ 31/Mar/11 ]

Fixed as per Randall's latest updated proposal





[JSR_333-21] Clarification of terms: "access control" and "Access Control Management" Created: 17/Dec/10  Updated: 25/Mar/11  Resolved: 25/Mar/11

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: mduerig Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issue Links:
Dependency
blocks JSR_333-9 Maintenance container Resolved
Issuezilla Id: 21

 Description   

Clarify and consistently use the terms 'access control' and 'Access
Control Management'. It is my understanding that 'access control' is the
general term for any kind of access control system while 'Access Control
Management' is the term used for the JCR specific access control system
as defined in §16. To that respect

  • the first sentence in the second paragraph of section 9.1. should
    change from

"In repositories that support Access Control this..."

to

"In repositories that support Access Control Management this...",

  • in 16.6.1 "access control" should be changed to "Access Control
    Management",
  • the capitalization of the terms "access control management" and
    "Access Control Management" should be unified.


 Comments   
Comment by mduerig [ 17/Dec/10 ]

blocks issue 9

Comment by Peeter Piegaze [ 25/Mar/11 ]

Fixed.





[JSR_333-22] 6.11.2 Node View inconsistent with javadocs Created: 11/Feb/11  Updated: 24/Mar/11  Resolved: 24/Mar/11

Status: Resolved
Project: jsr-333
Component/s: spec
Affects Version/s: current
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: jukka.zitting Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Section 6.11.2 Node View in the JSR 283 spec says the following about QueryResult.getNodes():

"For queries with more than one selector the order in
which nodes are returned is implementation-specific."

However, the javadoc for the same method says that a RepositoryException is thrown "if the query contains more than one selector".

The behaviour described in the javadoc is more appropriate in this case, so the text in the spec should be fixed.



 Comments   
Comment by Peeter Piegaze [ 24/Mar/11 ]

The incorrect sentence in the spec has been removed. In general the spec itself is not required to list every exception condition, so I have just removed the mention of the RepositoryException entirely. The javadoc mention of the error condition is sufficient.





[JSR_333-12] letting the repository name new collection members Created: 14/Sep/10  Updated: 17/Mar/11  Resolved: 17/Mar/11

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: New Feature Priority: Major
Reporter: reschke Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 12

 Description   

This may be out-of-scope, but I wanted to make sure it's mentioned and tracked.

In many cases, clients do not care what the name of a new collection member is.
And, in some case, repositories have areas where the server needs to assign new
names (for instance, UUID based).

This use case currently is not covered in JCR. The situation for WebDAV was the
same until recently (see RFC 5995).



 Comments   
Comment by reschke [ 18/Jan/11 ]

We could do this in at least two different ways:

1) Sneak the feature into the JCR name/path syntax, using a pattern that
currently is invalid. That would avoid having to define a new API, and work with
everything that adds new nodes, not just addNode.

2) We could add new signatures (such as addNode without relpath), or add a
completely new method.

Q1: any preference on the above?

Q2: AtomPub allows clients to suggest part of the name using the "Slug" header
(<http://greenbytes.de/tech/webdav/rfc5023.html#rfc.section.9.7>); do we want
something similar? Could be very useful in some cases, and comes with little
complexity for servers which can't do it.

Comment by geoffreyclemm [ 18/Jan/11 ]

A1: I would prefer to add new signatures, rather than play games with special
string values.

A2: I agree that giving a "hint" is desirable in many/most cases, so that is
worth doing.

Comment by Peeter Piegaze [ 25/Feb/11 ]

Alternatively, we could introduce a method that invents names based on a proposed parent path and hint.

Comment by Peeter Piegaze [ 01/Mar/11 ]

Proposal:

Add the following method to the Node interface:

/**

  • Returns a system-created JCR name that differs from the names
  • of all currently existing (and persisted) child nodes and properties
  • of this node. If present, the <code>hint</code> is used by
  • the system as the basis for the new name.
  • <p>
  • If the hint begins with a namespace in expanded form,
  • for example, " {http://example.com/ex}

    document",

  • then the system will attempt to create a name within
  • that namespace. If the namespace provided in the hint
  • has no existing local mapping then one is automatically
  • created (as per section 3.5.2 of the JCR specification).
  • <p>
  • If the hint begins with a namespace prefix in qualified form,
  • for example, "ex:document", then the system will attempt to
  • create a name in that namespace. If the namespace prefix
  • specified does not exist then the system will create a name
  • in the empty namespace.
  • <p>
  • If the hint does not begin with an expanded-form namespace or a prefix
  • then the name created will be in the empty namespace.
  • <p>
  • The name returned will always be a JCR name in qualified form
  • (as per section 3.2.6 of the JCR specification).
    *
  • @param hint A string to be used as the basis for the created name.
  • A value of <code>null</code> or the empty string means
  • that no hint is to be used.
    *
  • @return A system-created name different from all existing (persisted) child node and property names.
  • @since JCR 2.1
    */
    public String createChildName(String hint);
Comment by rhauch [ 01/Mar/11 ]

What are the advantages of adding a "createChildName(...)" method rather than another form of "addNode(...)" method? With the "createChildName(...)", the operation of creating a child is necessarily a two-step process, and it restricts the kinds of techniques an implementation can use to determine the child name.

For example, an implementation cannot really use a sequential algorithm. First of all, a session is not required to create the node with the generated name, so not all generated names might be used (resulting in out-of-sequence names). Second, a sequential algorithm can't base generated names solely upon the children that already exist, because multiple sessions calling 'createChildName()' before any session creates a node might result in all sessions getting the same generated name.

Wouldn't it be more flexible and less restrictive to use an 'addNode(...)' method with a new signature that might allow an implementation to create a node with a generated name? And, if the name were not necessarily fixed in stone until the session is saved, then an implementation could a much wider range of algorithm and techniques to generate the node names.

Was this approach considered?

Comment by Peeter Piegaze [ 01/Mar/11 ]

Yes, you are right about the limitations of the proposed approach. The only reason to do it this way would be to make it usable across more settings than just addNode. But if that is not needed, then an addNode variant would be better. How about addNodeWithHint(String hint) or addNodeAutoNamed(String hint)? If we did not need the hint, then of course addNode() would be fine too.

Comment by stefan_guggisberg [ 07/Mar/11 ]

currently there are 2 distinct addNode signatures:

addNode(String)
addNode(String, String)

IMO we'd need at least 2 additional signatures for supporting repository-generated node names.

if we agree on supporting repository-generated node names we should mention that this
only makes sense if the effective node type of the parent node includes residual child node
definitions.

Comment by Peeter Piegaze [ 10/Mar/11 ]

How about:

Node Node.addNodeAutoNamed()
Node Node.addNodeAutoNamed(String primaryNodeTypeName)

Comment by reschke [ 10/Mar/11 ]

...if we add a "String nameHint" to both...

Comment by Peeter Piegaze [ 16/Mar/11 ]

Ok, here is a proposal:

Add the following to the Node interface:

/**

  • Adds a new node with a system-generated name as a direct child of <code>this</code> node and returns
  • the new node. The name of the new node is a system-created JCR name that differs from
  • the names of all currently persisted child nodes and
  • properties of <code>this</code> node. If present, the <code>nameHint</code>
  • is used as the basis for the name of the new node.
  • <p>
  • This is <i>session-write</i> method, meaning that the addition of the new
  • node is dispatched upon {@link Session#save}

    .

  • <p>
  • For the method to successfully add the new child node, the effective node type
  • of <code>this</code> node must permit <i>residual child nodes</i> (see section
  • 3.7.2.1 of the JCR 2.1 specification). If this condion is not met, a
  • <code>ConstraintViolationException</code> will be thrown either immediately, on
  • dispatch (save, whether within or without transactions) or on persist
  • (save without transactions, commit within a transaction). Implementations may
  • differ on when this validation is performed.
  • <p>
  • A <code>VersionException</code> will be thrown either immediately, on
  • dispatch (save, whether within or without transactions) or on persist
  • (save without transactions, commit within a transaction), if the node to
  • which the new child is being added is read-only due to a checked-in node.
  • Implementations may differ on when this validation is performed.
  • <p>
  • A <code>LockException</code> will be thrown either immediately, on
  • dispatch (save, whether within or without transactions) or on persist
  • (save without transactions, commit within a transaction), if a lock
  • prevents the addition of the node. Implementations may differ on when
  • this validation is performed.
  • <p>
  • The new node's primary node type will be determined by the residual child node
  • definitions in the node types of its parent. This may occur either
  • immediately, on dispatch (save, whether within or without transactions)
  • or on persist (save without transactions, commit within a transaction),
  • depending on the implementation.
  • <p>
  • If ordering is supported by the node type of the parent node of the new
  • node then the new node is appended to the end of the child node list.
  • <p>
  • The behavior of name generation for the new node depends on the form of the
  • <code>nameHint</code> parameter. If <code>nameHint</code> is:
  • <li>
  • <ol>
  • <code>null</code>:
  • The new node name will be generated entirely by the repository.
  • The namespace used for the new name may depend on implementation-specific
  • configuration.
  • </ol>
  • <ol>
  • <code>""</code> (the empty string), <code>":"</code> (colon) or <code>"{}"</code>:
  • The new node name will be in the empty namespace and
  • the local part of the name will be generated by the repository.
  • </ol>
  • <ol>
  • <code>"<i>somePrefix</i>:"</code> where <code><i>somePrefix</i></code> is
  • a syntactically valid namespace prefix: The repository will attempt
  • to create a name in the namespace represented by that prefix. If the prefix
  • specified does not exist, then a <code>NameSpaceException</code> is thrown either immediately, on
  • dispatch (save, whether within or without transactions) or on persist
  • (save without transactions, commit within a transaction).
  • If the prefix does exist then the local part of the name is generated by the repository.
  • </ol>
  • <ol>
  • <code>" {<i>someURI</i>}"</code> where <code><i>someURI</i></code> is
    * a syntactically valid namespace URI: The repository will attempt
    * to create a name in the namespace specified. If that namespace
    * has no existing local mapping to a prefix then one is automatically
    * created (as per section 3.5.2 of the JCR specification). The local part
    * of the name is generated by the repository.
    * </ol>
    * <ol>
    * <code>"<i>somePrefix</i>:<i>localNameHint<i>"</code> where <code><i>somePrefix</i></code> is
    * a syntactically valid namespace prefix and <i>localNameHint<i> is syntactically valid local name:
    * The repository will attempt to create a name in the namespace represented by that prefix as
    * described above. The local part of the name is generated by the repository using <i>localNameHint<i>
    * as a basis. The way in which the local name is contructed from the hint may vary across implementations.
    * </ol>
    * <ol>
    * <code>"{<i>someURI</i>}

    <i>localNameHint<i>"</code> where <code><i>someURI</i></code> is

  • a syntactically valid namespace URI and <i>localNameHint<i> is syntactically valid local name:
  • The repository will attempt to create a name in the namespace specified as described in (3), above.
  • The local part of the name is generated by the repository using <i>localNameHint<i>
  • as a basis. The way in which the local name is contructed from the hint may vary across implementations.
  • </ol>
  • </li>
  • @param nameHint A string to be used as the basis for the created name or <code>null</code>.
  • @return The newly created node.
  • @since JCR 2.1
  • @throws ConstraintViolationException if <code>this</code> node does not allow residual child nodes
  • and this implementation performs this validation immediately.
  • @throws VersionException if <code>this</code> is read-only due to a checked-in node
  • and this implementation performs this validation immediately.
  • @throws LockException if a lock prevents the addition of the node
  • and this implementation performs this validation immediately.
  • @throws NameSpaceException if a namespace prefix is provided in the <code>nameHint</code> which does not exist
  • and this implementation performs this validation immediately.
    */
    public Node addNodeAutoNamed(String nameHint);

/**

  • Adds a new node of the specified primary node type with a system-generated name
  • as a direct child of <code>this</code> node and returns
  • the new node. The name of the new node is a system-created JCR name that differs from
  • the names of all currently persisted child nodes and
  • properties of <code>this</code> node. If present, the <code>nameHint</code>
  • is used as the basis for the name of the new node.
  • The behavior of this method is identical to {@link #addNodeAutoNamed(String nameHint)}
  • except that the primary node type of the new node is explicitly
  • specified.
  • @param nameHint A string to be used as the basis for the created name or <code>null</code>.
    *
  • @param primaryNodeTypeName The primary node type of the new node.
  • @return The newly created node.
  • @since JCR 2.1
  • @throws ConstraintViolationException if <code>this</code> node does not allow residual child nodes
  • of the specified node type
  • and this implementation performs this validation immediately.
  • @throws VersionException if <code>this</code> is read-only due to a checked-in node
  • and this implementation performs this validation immediately.
  • @throws LockException if a lock prevents the addition of the node
  • and this implementation performs this validation immediately.
  • @throws NameSpaceException if a namespace prefix is provided in the <code>nameHint</code> which does not exist
  • and this implementation performs this validation immediately.
    */
    public Node addNodeAutoNamed(String nameHint, String primaryNodeTypeName);
Comment by rhauch [ 16/Mar/11 ]

Peeter, that proposal looks good to me.

Comment by stefan_guggisberg [ 17/Mar/11 ]

+1 for peet's proposal

Comment by Peeter Piegaze [ 17/Mar/11 ]

Added the two new methods as mentioned above in src and spec.





[JSR_333-17] Provide a Node#setMixins(String[] mixinNames) method Created: 15/Oct/10  Updated: 01/Mar/11  Resolved: 01/Mar/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: stefan_guggisberg Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 17

 Description   

assume the following scenario:

  • mixin A declares the mandatory property p
  • mixin A' extends from A
  • node n has mixin A'
  • we'd like to migrate/downgrade node n from mixin A' to A

with an implementation where addMixin/removeMixin take effect
immediately, there's no easy way of replacing the assigned mixins.

assigning A first results in a NOP since A would be redundant.
removing A' first removes the mandatory property p.

a new method Node.setMixins(String[]) would allow to migrate
a node from mixin A' to A while preserving 'shared' content.
the semantics of Node.setMixins(String[]) would be similar to
Node.setPrimaryType(String).

related Apache Jackrabbit issues:

https://issues.apache.org/jira/browse/JCR-2011
https://issues.apache.org/jira/browse/JCR-2772



 Comments   
Comment by stefan_guggisberg [ 18/Oct/10 ]

corresponding Apache Jackrabbit issue:
https://issues.apache.org/jira/browse/JCR-2788

Comment by Peeter Piegaze [ 01/Mar/11 ]

Added the following method to Node:

/**

  • Sets this node's mixin node types to those named in <code>mixinNames</code> and sets the
  • this node's <code>jcr:mixinTypes</code> property accordingly. Any previous mixins are removed.
  • <p>
  • Semantically, the new node type <i>may</i> take effect immediately, on
  • dispatch or on persist. The behavior adopted must be the same as the
  • behavior adopted for {@link #setPrimaryType}

    and the behavior that occurs

  • when a node is first created.
  • <p>
  • This method adds (and if necessary removes) mixins in a single atomic step, avoiding
  • constraint violations that might occur if the steps were done individually. This can be
  • useful when changing node types while preserving existing content.
  • <p>
  • A <code>ConstraintViolationException</code> is thrown either immediately,
  • on dispatch or on persist, if a conflict occurs within set of assigned mixins or
  • the primary node type or for an implementation-specific reason.
  • Implementations may differ on when this validation is done.
  • <p>
  • In some implementations it may only be possible to set mixin types before
  • a a node is persisted <i>for the first time</i>. In such cases any later
  • calls to <code>setMixin</code> will throw a <code>ConstraintViolationException</code>
  • either immediately, on dispatch or on persist.
  • <p>
  • A <code>NoSuchNodeTypeException</code> is thrown either immediately, on
  • dispatch or on persist, if one or more of the specified <code>mixinNames</code> are not
  • recognized. Implementations may differ on when this validation is done.
  • <p>
  • A <code>VersionException</code> is thrown either immediately, on dispatch
  • or on persist, if this node is read-only due to a checked-in node.
  • Implementations may differ on when this validation is done.
  • <p>
  • A <code>LockException</code> is thrown either immediately, on dispatch or
  • on persist, if a lock prevents the addition of the mixin. Implementations
  • may differ on when this validation is done.
    *
  • @param mixinNames the names of the mixin node types to be set
  • @throws NoSuchNodeTypeException If one or more of the specified <code>mixinNames</code>
  • are not recognized and this implementation performs this validation
  • immediately.
  • @throws ConstraintViolationException if the specified mixin node types
  • create a conflict and this implementation performs this validation
  • immediately.
  • @throws VersionException if this node is read-only due to a checked-in
  • node and this implementation performs this validation immediately.
  • @throws LockException if a lock prevents the addition of the mixins and
  • this implementation performs this validation immediately.
  • @throws RepositoryException if another error occurs.
  • @since JCR 2.1
    */
    public void setMixins(String[] mixinNames) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException;




[JSR_333-16] Javadoc of RangeIterator#getSize() refers to non-existing getNumberRemaining Created: 12/Oct/10  Updated: 01/Mar/11  Resolved: 01/Mar/11

Status: Resolved
Project: jsr-333
Component/s: api
Affects Version/s: current
Fix Version/s: milestone 1

Type: Bug Priority: Major
Reporter: anchela Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 16

 Description   

At some point of time in jsr 283 specification phase the RangeIterator had a
method getNumberRemaining() that was dropped again later on.

However, the Javadoc of #getSize() hasn't been adjusted when removing the new
method again and still refers to getNumberRemaining().



 Comments   
Comment by Peeter Piegaze [ 01/Mar/11 ]

Fixed: the reference to the non-existent method has been removed in src.





[JSR_333-2] Add NodeType.getSupertypeNames() Created: 01/Sep/10  Updated: 24/Feb/11  Resolved: 24/Feb/11

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: Peeter Piegaze Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 2

 Description   

JSR 283 issue #397 was deferred to JCR 2.1. Below is a copy of the comments from the 283 issue:

---------

To allow for efficient queries, and for symmetry to parallel:

  • NodeType[] NodeType.getDeclaredSupertypes()
  • String[] NodeTypeDefinition.getDeclaredSupertypeNames()
  • NodeType[] NodeType.getSupertypes()

I would like to request the addition of:

  • String[] NodeType.getSupertypeNames()

Proposed Javadoc:

Returns the names of all supertypes of this node type in the node type inheritance hierarchy. For
primary types apart from nt:base, this list will always include at least nt:base. For mixin types, there is
no required supertype.

------- Additional comments from fguillaume Mon Apr 14 13:13:40 +0000 2008 -------

This is still an issue in RC17.
I suggest adding the following code in NodeType.java:

/**

  • Returns the names of all supertypes of this node type in the node type
  • inheritance hierarchy.
  • <p/>
  • For primary types apart from <code>nt:base</code>, this list will always
  • include at least <code>nt:base</code>. For mixin types, there is no
  • required supertype.
    *
  • @see #getSupertypes
  • @see NodeTypeDefinition#getDeclaredSupertypeNames
    *
  • @return an array of <code>String</code>s
    */
    public String[] getSupertypeNames();

------- Additional comments from ppiegaze Wed Jul 23 22:47:01 +0000 2008 -------

As per costa mesa F2F, defer to JCR 2.1



 Comments   
Comment by Peeter Piegaze [ 01/Sep/10 ]

Changed from Defect to Enhancement

Comment by Peeter Piegaze [ 24/Feb/11 ]

Added NodeType.getSupertypeNames() to spec and src (rev. 14)





[JSR_333-1] Provide a Node#rename(String) method Created: 16/Aug/10  Updated: 24/Feb/11  Resolved: 24/Feb/11

Status: Resolved
Project: jsr-333
Component/s: www
Affects Version/s: current
Fix Version/s: milestone 1

Type: Improvement Priority: Major
Reporter: stefan_guggisberg Assignee: Peeter Piegaze
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 1

 Description   

currently there's no easy way for renaming a node at its current position within the (orderable)
collection of sibling child nodes.

i suggest we add the following method to the Node interface:

void rename(String newName)
throws ItemExistsException, VersionException, ConstraintViolationException,
LockException, RepositoryException.

this issue has been originally raised in jackrabbit:
http://issues.apache.org/jira/browse/JCR-2683



 Comments   
Comment by Peeter Piegaze [ 24/Sep/10 ]

changed platform to All

Comment by Peeter Piegaze [ 24/Feb/11 ]

Added Node.rename in spec and javadoc (rev. 13)





Generated at Sun Apr 26 16:49:55 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.