blob: 51e8874b419162f577bedc523e2927a55359872a [file] [log] [blame]
/*
* 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.felix.webconsole.internal;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
/**
* The <code>Util</code> class contains various utility methods used internally
* by the web console implementation and the build-in plugins.
*/
public class Util {
/**
* Return a display name for the given <code>bundle</code>:
* <ol>
* <li>If the bundle has a non-empty <code>Bundle-Name</code> manifest
* header that value is returned.</li>
* <li>Otherwise the symbolic name is returned if set</li>
* <li>Otherwise the bundle's location is returned if defined</li>
* <li>Finally, as a last resort, the bundles id is returned</li>
* </ol>
*
* @param bundle the bundle which name to retrieve
* @param locale the locale, in which the bundle name is requested
* @return the bundle name - see the description of the method for more details.
*/
public static String getName( Bundle bundle, Locale locale )
{
final String loc = locale == null ? null : locale.toString();
String name = ( String ) bundle.getHeaders( loc ).get( Constants.BUNDLE_NAME );
if ( name == null || name.length() == 0 )
{
name = bundle.getSymbolicName();
if ( name == null )
{
name = bundle.getLocation();
if ( name == null )
{
name = String.valueOf( bundle.getBundleId() );
}
}
}
return name;
}
/**
* Returns the value of the header or the empty string if the header
* is not available.
*
* @param bundle the bundle which header to retrieve
* @param headerName the name of the header to retrieve
* @return the header or empty string if it is not set
*/
public static String getHeaderValue( Bundle bundle, String headerName )
{
Object value = bundle.getHeaders().get(headerName);
if ( value != null )
{
return value.toString();
}
return "";
}
/**
* Orders the bundles according to their name as returned by
* {@link #getName(Bundle, Locale)}, with the exception that the system bundle is
* always place as the first entry. If two bundles have the same name, they
* are ordered according to their version. If they have the same version,
* the bundle with the lower bundle id comes before the other.
*
* @param bundles the bundles to sort
* @param locale the locale, used to obtain the localized bundle name
*/
public static void sort( Bundle[] bundles, Locale locale )
{
Arrays.sort( bundles, new BundleNameComparator( locale ) );
}
/**
* This method expects a locale string in format language_COUNTRY, or
* language. The method will determine which is the correct form of locale
* string and construct a <code>Locale</code> object.
*
* @param locale the locale string, if <code>null</code> - default locale is
* returned
* @return a locale object
* @see Locale
*/
public static final Locale parseLocaleString(String locale)
{
if (locale == null)
{
return Locale.getDefault();
}
int idx = locale.indexOf('_');
String language;
String country = "";
if (idx < 0)
{ // "en"
language = locale;
}
else
{ // "en_US"
language = locale.substring(0, idx); // "en"
idx++; // "_"
int last = locale.indexOf('_', idx); // "US"
if (last < 0)
{
last = locale.length();
}
country = locale.substring(idx, last);
}
return new Locale(language, country);
}
private static final class BundleNameComparator implements Comparator<Bundle>
{
private final Locale locale;
BundleNameComparator( final Locale locale ) {
this.locale = locale;
}
public int compare( Bundle b1, Bundle b2 )
{
// the same bundles
if ( b1 == b2 || b1.getBundleId() == b2.getBundleId() )
{
return 0;
}
// special case for system bundle, which always is first
if ( b1.getBundleId() == 0 )
{
return -1;
}
else if ( b2.getBundleId() == 0 )
{
return 1;
}
// compare the symbolic names
int snComp = Util.getName( b1, locale ).compareToIgnoreCase( Util.getName( b2, locale ) );
if ( snComp != 0 )
{
return snComp;
}
// same names, compare versions
Version v1 = Version.parseVersion( ( String ) b1.getHeaders().get( Constants.BUNDLE_VERSION ) );
Version v2 = Version.parseVersion( ( String ) b2.getHeaders().get( Constants.BUNDLE_VERSION ) );
int vComp = v1.compareTo( v2 );
if ( vComp != 0 )
{
return vComp;
}
// same version ? Not really, but then, we compare by bundle id
if ( b1.getBundleId() < b2.getBundleId() )
{
return -1;
}
// b1 id must be > b2 id because equality is already checked
return 1;
}
}
public static void sendJsonOk(final HttpServletResponse response) throws IOException
{
response.setContentType( "application/json" ); //$NON-NLS-1$
response.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
response.getWriter().print( "{ \"status\": true }" ); //$NON-NLS-1$
}
public static final Locale getLocale( final HttpServletRequest request ) {
try {
return request.getLocale();
} catch ( Throwable t ) {
// expected in standard OSGi Servlet 2.1 environments
// fallback to using the default locale
return Locale.getDefault();
}
}
public static String getStringProperty( final ServiceReference<?> service, final String propertyName ) {
final Object property = service.getProperty( propertyName );
if ( property instanceof String ) {
return ( String ) property;
}
return null;
}
}