OK, I have implemented and attached a Version class with the desired
behavior and tested that the following works as expected
System.out.println("toString:" + new Version("5.0.3", "*"));
System.out.println("hashCode:" + new Version("5.0.3", "*").hashCode());
System.out.println("not equals:" + new Version("5.0.3",
"*").equals(new Version("5", "*")));
System.out.println("compareTo == 0:" + new Version("5.0.3",
"*").compareTo(new Version("5", "*")));
System.out.println("compareTo == +:" + new Version("5.0.3",
"*").compareTo(new Version("5", "0")));
System.out.println("compareTo == -:" + new Version("5.0.3",
"*").compareTo(new Version("5.0.4", "*")));
Given the way that compareTo works, I changed the wildcard behavior from
what is listed before to make the wildcard behavior only affect
compareTo() results of 0. However, this still has the desired effect
because min- and max- comparisons are <= and >= respectively. Anway, I
believe looking at the code in compareTo() will give everyone a better
idea of what I intend.
Note also that I am unsure what package this should be in. I placed it
in the trinidad api context class simply because that is where the
Triniad Agent is and I would eventually expect this Object to be
returned by the Agent.
-- Blake Sullivan
Blake Sullivan said the following On 4/18/2008 3:15 PM PT:
OK, how about
option 5) the version feature is a String that matches the native
"major.minor.whatever" format of the browser's engine. If the
browser's engine uses non "." for separating versions, "." is used
instead.
For matches, the "*" character is allowed in any version section.
For comparisons, the "*" is always a valid match regardless of <, >,
or = comparison
For comparisons where the comparison side contains fewer version
sections than the actual browser version, the comparison side is
padded with * version sections and the comparison occurs as above.
For comparisons where the comparison side contains more version
sections than the actual browser version, the browser version is
padded with 0 version sections and the comparison occurs as above.
// user wants to match IE 5, actual browser version ie 5.5
@agent ie and (version:5)
matches because version:5 expands to version 5.* and 5.* matches 5.5
@agent ie and (min-version:5)
matches because version:5 expands to version 5.* and 5.* < 5.5 = true
@agent ie and (max-version:5)
matches because version:5 expands to version 5.* and 5.* > 5.5 = true
// actual browser version gecko 1.9
@agent gecko and (min-version:1.9.2)
does not match because the browser version 1.9 expands to 1.9.0 and
1.9.2 is > than 1.9.0
// actual browser version gecko 1.9
@agent gecko and (min-version:1.9.*)
matches because the browser version 1.9 expands to 1.9.0 and 1.9.* ==
1.9.0
-- Blake Sullivan
Blake Sullivan said the following On 4/17/2008 12:31 PM PT:
If we agree that we like the we like the media query syntax and that
the only issue is how to handle less than (as opposed the <=) for the
max-version, then we can just collect up the proposals and pick one:
1) The verbose and explicit (max-version-less-than:8).
2) Define that for the version feature, max-version means < not <=.
Inconsistent with other uses of max (max-version:8)
3) Let the skinning author provide enough precision to avoid the need
to distinguish between < 8 and <= a number that apporaches 8
(max-version:7.99)
4) Add an operator suffix (max-version-lt:8)
1) is gross
2) is potentially confusing due to inconsistency
3) might not be immediately obvious and could theoretically have
precision problems
4) is not immediately obvious either but incredibly flexible
I vote for 3) since it gets the job done and doesn't preclude doing
more later.
-- Blake Sullivan
Andrew Robinson said the following On 4/17/2008 11:53 AM PT:
http://www.w3.org/TR/REC-CSS2/media.html
@import url("loudvoice.css") aural;
so here are multiple groups of characters that show that spaces are
acceptable (import url and aural keywords in one "bunch")
url("loudvoice.css")
shows that parenthesis with at least one argument is acceptable
@media screen, print {
Shown that a comma separated list, unlike normal CSS selectors applies
to the whole @ (meaning that it wasn't "@meda screen, @media print")
From css3 (http://www.w3.org/TR/css3-reader/):
@import "my-print-style.css" print;
here, a quoted string is permissible (goes with the url values in
CSS rules)
<?xml-stylesheet href="style1.css" type="text/css"
media="screen and (color) and (max-width: 400px"?>
<?xml-stylesheet href="style2.css" type="text/css"
media="reader and (max-device-ratio: 1/1)"?>
Hmmm.... interesting, but do we want to reuse something that relates
to CSS but is not in a CSS file?
@media reader and (grid: 0)
Ah, now we are talking. This looks like what Blake was referring to
From http://www.css3.info/preview/media-queries/:
@media all and (min-width: 640px) {
Even better, showing an "all" keyword and having "normal CSS
properties" in parens.
http://www.css3.info/preview/attribute-selectors/:
Do we dare take RegExp like syntax from attr. selectors and apply them
to @agent rules?
So I can see Blake's suggestion being backed by these, but IMO
"max-version-less-than:8" is too long to remember.
Perhaps just:
IE 5.5 or greater:
@agent ie and (min-version: 5.5)
IE 5.0 or greater:
@agent ie and (min-version: 5)
IE >= 5.0 and < 6.0:
@agent ie and (version: 5)
or (I like this one less):
@agent ie and (major-version: 5)
IE <= 6.0:
@agent ie and (max-version: 6)
IE < 6:
@agent ie and (max-version: 5.9)
IE >= 6.0 and < 8.0:
@agent ie and (min-version: 6) and (max-version: 7.9)
same as:
@agent ie and (min-version: 6) and (max-version: 7)
IE >= 6.0 and <= 8.0:
@agent ie and (min-version: 6) and (max-version: 8.0)
IE >= 6.0 and <= 8.x:
@agent ie and (min-version: 6) and (max-version: 8)
So x.y (ie 5.5) means precisely that, no vagueness and x (ie 6) means
major version x regardless of minor version. If it is too hard to
parse the decimal and remember it, "max-major-version",
"min-major-version" and "major-version" could be used for integer only
comparison with the major version and "max-version", "min-version" and
"version" could be used for full major.minor comparison.
I think using something like 7.9 or 7.99 could theoretically be used
for less than but not equal to. I think the fewer number of keywords
the clearer it will be to use. Just my opinion.
Just adding some thoughts to chew on since concrete ideas were asked
for.
-Andrew
On Thu, Apr 17, 2008 at 12:26 PM, Cristi Toth
<[EMAIL PROTECTED]> wrote:
Hi guys,
You're right, I should have discussed the format before committing it.
I started fixing the issue using the format that was specified
there...
(there weren't to many comments on that issue btw...)
During I was fixing it, I noticed that XSS suppported multiple
versions,
so I adapted what was suggested on the issue to support that too.
Anyway, lets get this subject out in a new thread
and stick here to discussing the format.
Guys, those of you that suggested some general guidelines, they all
sound
good,
but please try to think of some concrete format that comply with those
guidelines.
If we decide a final format and implement it until its get
released, then no
big harm done.
So please be constructive ;)
Thanks for any feedback!
cheers,
--
Cristi Toth
-------------
Codebeat
www.codebeat.ro
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.trinidad.context;
import java.util.Arrays;
import java.util.regex.Pattern;
/**
* Immutable Representation of a dot-separated version.
*
* This representation
* allows individual sections of the version to be wild-carded and allows
* for comparisons between Versions with different numbers of version
* subsections to be compared. When comparing Versions, each version
* subsection is compared from left to right. If one Version doesn't have
* a version subsection at the current index, the value of versionPadding
* is used for this comparison. Version subsections with the wild-card value
"*"
* care considered equal. The value returned by compareTo() is the value of the
* first non-equal version subsection or zero if all subsections match.
*
* Due to the support for wild-cards, this class has a natural ordering
* that is inconsistent with equals. For example,
* <code>Version("5", "*").compareTo(Version("5.0", "*") == 0</code>
* <code>Version("5", "*").equals(Version("5.0", "*") == false;</code>
* @author Blake Sullivan
*/
public final class Version implements Comparable<Version>
{
/**
* Creates a Version instance from the dot-separated Version String and the
* versionPadding.
* @param version The dot-separated version to represent
* @param versionPadding The value to return for sub-version sections
* requested beyond the sub-version sections present in the version String
* @throws NullPointerException if version or versionPadding are null
* @throws IllegalArgumentException if version or versionPadding are the
* empty String
*/
public Version(String version, String versionPadding)
{
_checkNonEmptyString(version, "version");
_checkNonEmptyString(version, "versionPadding");
// build the array of subversions
_versions = _DOT_SPLITTER.split(version, 0);
_versionPadding = versionPadding;
// sicne we're immutable, we might as well calculate this up front
// while we still have the String version around
_hashCode = version.hashCode() * 37 + versionPadding.hashCode();
}
/**
* When comparing Versions, each version
* subsection is compared from left to right. If one Version doesn't have
* a version subsection at the current index, the value of versionPadding
* is used for this comparison. Version subsections with the wild-card value
"*"
* care considered equal. The value returned by compareTo() is the value of
the
* first non-equal version subsection or zero if all subsections match.
* @param otherVersion The Version object to compare this Version Object with
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*/
public int compareTo(Version otherVersion)
{
int ourVersionCount = _versions.length;
int otherVersionCount = otherVersion._versions.length;
int compareCount = (ourVersionCount > otherVersionCount)
? ourVersionCount
: otherVersionCount;
for (int versionIndex = 0; versionIndex < compareCount; versionIndex++)
{
String ourSubVersion = _getSubVersion(versionIndex);
String otherSubVersion = otherVersion._getSubVersion(versionIndex);
// treat "*" wildcard as equals
if ("*".equals(ourSubVersion) || "*".equals(otherSubVersion))
{
continue;
}
else
{
// compare the sub-result
int result = ourSubVersion.compareTo(otherSubVersion);
// not equal, so return the result
if (result != 0)
return result;
}
}
// equivalent
return 0;
}
@Override
public String toString()
{
// rebuild the initial version string from the split array
StringBuilder versionBuilder = new StringBuilder();
int versionCount = _versions.length;
for (int i = 0;;)
{
versionBuilder.append(_versions[i]);
i++;
if (i != versionCount)
versionBuilder.append('.');
else
break;
}
return versionBuilder.toString();
}
@Override
public boolean equals(Object o)
{
if (o == this)
return true;
else if (!(o instanceof Version))
return false;
else
{
Version otherVersion = (Version)o;
// we are equal if all of version content and padding are equal
return _versionPadding.equals(otherVersion._versionPadding) &&
Arrays.equals(_versions, otherVersion._versions);
}
}
@Override
public int hashCode()
{
// used cached version
return _hashCode;
}
/**
* Returns the contents of the sub-version section of the overall version,
* padding the result with the version padding if the version section
* index is greater than the number of actual version sections in this
* version
* @param versionIndex index of the "." version section from the left side
* of the version string.
* @return The content of the version section if available, otehrwise the
* versionPadding
*/
private String _getSubVersion(int versionIndex)
{
if (versionIndex >= _versions.length)
return _versionPadding;
else
return _versions[versionIndex];
}
private void _checkNonEmptyString(String checkedString, String identifier)
{
if (checkedString == null)
throw new NullPointerException(identifier + " must be non-null");
if (checkedString.length() == 0)
throw new IllegalArgumentException(identifier + " must be non-empty");
}
private final String[] _versions;
private final String _versionPadding;
private final int _hashCode;
// cache the compiled splitter
private static final Pattern _DOT_SPLITTER = Pattern.compile("\\.");
}