blob: ba5aaa0f4f0fded1db80392be7bb5bddf73cadca [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.plugins.obr.internal;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.ServletException;
import org.apache.felix.bundlerepository.Capability;
import org.apache.felix.bundlerepository.Property;
import org.apache.felix.bundlerepository.Reason;
import org.apache.felix.bundlerepository.Repository;
import org.apache.felix.bundlerepository.RepositoryAdmin;
import org.apache.felix.bundlerepository.Requirement;
import org.apache.felix.bundlerepository.Resolver;
import org.apache.felix.bundlerepository.Resource;
import org.apache.felix.utils.json.JSONWriter;
import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
/**
* This class provides a plugin for rendering the available OSGi Bundle Repositories
* and the resources they provide.
*/
class FelixBundleRepositoryRenderHelper extends AbstractBundleRepositoryRenderHelper
{
FelixBundleRepositoryRenderHelper( AbstractWebConsolePlugin logger, BundleContext bundleContext )
{
super( logger, bundleContext, RepositoryAdmin.class.getName() );
}
@Override
String getData( final String filter, final boolean details, Bundle[] bundles )
{
RepositoryAdmin admin = ( RepositoryAdmin ) getRepositoryAdmin();
if ( admin != null )
{
final StringWriter sw = new StringWriter();
JSONWriter json = new JSONWriter(sw);
try
{
json.object();
json.key( "status" ); //$NON-NLS-1$
json.value(true);
json.key( "details" ); //$NON-NLS-1$
json.value(details);
final Repository repositories[] = admin.listRepositories();
if ( repositories != null )
{
json.key("repositories");//$NON-NLS-1$
json.array();
for ( int i = 0; repositories != null && i < repositories.length; i++ )
{
json.object();
json.key( "lastModified"); //$NON-NLS-1$
json.value( repositories[i].getLastModified());
json.key( "name"); //$NON-NLS-1$
json.value(repositories[i].getName() );
json.key( "url"); //$NON-NLS-1$
json.value( repositories[i].getURI() );
json.endObject();
}
json.endArray();
}
Resource[] resources = admin.discoverResources( filter );
if ( resources != null )
{
json.key("resources");//$NON-NLS-1$
json.array();
for ( int i = 0; i < resources.length; i++ )
{
toJSON( json, resources[i], bundles, details );
}
json.endArray();
}
json.endObject();
json.flush();
}
catch ( IOException e )
{
logger.log( "Failed to serialize repository to JSON object.", e );
}
catch ( Exception e )
{
logger.log( "Failed to parse filter '" + filter + "'", e );
try
{
String reason = "filter=" + filter;
if ( e.getMessage() != null )
{
reason = e.getMessage() + "(" + reason + ")";
}
json.key("error"); //$NON-NLS-1$
json.value( reason );
json.endObject();
json.flush();
}
catch ( IOException je )
{
// ignore
}
}
return sw.toString();
}
// fall back to no data
return "{}"; //$NON-NLS-1$
}
@Override
final void doAction( String action, String urlParam ) throws IOException, ServletException
{
RepositoryAdmin admin = ( RepositoryAdmin ) getRepositoryAdmin();
Repository[] repos = admin.listRepositories();
Repository repo = getRepository( repos, urlParam );
String uri = repo != null ? repo.getURI() : urlParam;
if ( "delete".equals( action ) ) //$NON-NLS-1$
{
if ( !admin.removeRepository( uri ) )
{
throw new ServletException( "Failed to remove repository with URL " + uri );
}
}
else if ( "add".equals( action ) || "refresh".equals( action ) ) //$NON-NLS-1$ //$NON-NLS-2$
{
try
{
admin.addRepository( uri );
}
catch ( IOException e )
{
throw e;
}
catch ( Exception e )
{
throw new ServletException( "Failed to " + action + " repository " + uri + ": " + e.toString() );
}
}
}
@Override
final void doDeploy( String[] bundles, boolean start, boolean optional )
{
try
{
// check whether we have to do something
if ( bundles == null || bundles.length == 0 )
{
logger.log( "No resources to deploy" );
return;
}
RepositoryAdmin repoAdmin = ( RepositoryAdmin ) getRepositoryAdmin();
Resolver resolver = repoAdmin.resolver();
// prepare the deployment
for ( int i = 0; i < bundles.length; i++ )
{
String bundle = bundles[i];
if ( bundle == null || bundle.equals( "-" ) ) //$NON-NLS-1$
{
continue;
}
String filter = "(id=" + bundle + ")";
Resource[] resources = repoAdmin.discoverResources( filter );
if ( resources != null && resources.length > 0 )
{
resolver.add( resources[0] );
}
}
FelixDeployer.deploy( resolver, logger, start, optional );
}
catch ( InvalidSyntaxException e )
{
throw new IllegalStateException( e );
}
}
private final Repository getRepository( Repository[] repos, String repositoryUrl )
{
if ( repositoryUrl == null || repositoryUrl.length() == 0 )
{
return null;
}
for ( int i = 0; i < repos.length; i++ )
{
if ( repositoryUrl.equals( repos[i].getURI() ) )
{
return repos[i];
}
}
return null;
}
private final void toJSON( JSONWriter writer, Resource resource, Bundle[] bundles, boolean details ) throws IOException
{
final String symbolicName = resource.getSymbolicName();
final Version version = resource.getVersion();
String installed = "";
for ( int i = 0; symbolicName != null && installed.length() == 0 && bundles != null && i < bundles.length; i++ )
{
final Version ver = bundles[i].getVersion();
if ( symbolicName.equals(bundles[i].getSymbolicName()))
{
installed = ver.toString();
}
}
writer.object();
writer.key( "id"); //$NON-NLS-1$
writer.value(resource.getId() );
writer.key( "presentationname" ); //$NON-NLS-1$
writer.value(resource.getPresentationName() );
writer.key( "symbolicname" ); //$NON-NLS-1$
writer.value( symbolicName );
writer.key( "url"); //$NON-NLS-1$
writer.value(resource.getURI() );
writer.key( "version" ); //$NON-NLS-1$
writer.value(version );
writer.key( "categories" ); //$NON-NLS-1$
writer.value(resource.getCategories() );
writer.key( "installed" ); //$NON-NLS-1$
writer.value(installed );
if ( details )
{
Capability[] caps = resource.getCapabilities();
if ( caps != null )
{
writer.key("capabilities"); //$NON-NLS-1$
writer.array();
for ( int i = 0; i < caps.length; i++ )
{
writer.object();
writer.key( "name" ); //$NON-NLS-1$
writer.value(caps[i].getName() );
writer.key( "properties" ); //$NON-NLS-1$
toJSON( writer, caps[i].getProperties() );
writer.endObject();
}
writer.endArray();
}
Requirement[] reqs = resource.getRequirements();
if ( reqs != null )
{
writer.key("requirements"); //$NON-NLS-1$
writer.array();
for ( int i = 0; i < reqs.length; i++ )
{
writer.object();
writer.key( "name" ); //$NON-NLS-1$
writer.value(reqs[i].getName() );
writer.key( "filter" ); //$NON-NLS-1$
writer.value(reqs[i].getFilter() );
writer.key( "optional" ); //$NON-NLS-1$
writer.value(reqs[i].isOptional() );
writer.endObject();
}
writer.endArray();
}
final RepositoryAdmin admin = ( RepositoryAdmin ) getRepositoryAdmin();
Resolver resolver = admin.resolver();
resolver.add( resource );
resolver.resolve( Resolver.NO_OPTIONAL_RESOURCES );
Resource[] required = resolver.getRequiredResources();
if ( required != null )
{
writer.key("required"); //$NON-NLS-1$
writer.array();
for ( int i = 0; required != null && i < required.length; i++ )
{
toJSON( writer, required[i], bundles, false );
}
writer.endArray();
}
Resource[] optional = resolver.getOptionalResources();
if ( optional != null )
{
writer.key("optional"); //$NON-NLS-1$
writer.array();
for ( int i = 0; optional != null && i < optional.length; i++ )
{
toJSON( writer, optional[i], bundles, false );
}
writer.endArray();
}
Reason[] unsatisfied = resolver.getUnsatisfiedRequirements();
if ( unsatisfied != null)
{
writer.key("unsatisfied"); //$NON-NLS-1$
writer.array();
for ( int i = 0; unsatisfied != null && i < unsatisfied.length; i++ )
{
writer.object();
writer.key( "name" ); //$NON-NLS-1$
writer.value(unsatisfied[i].getRequirement().getName() );
writer.key( "filter" ); //$NON-NLS-1$
writer.value(unsatisfied[i].getRequirement().getFilter() );
writer.key( "optional" ); //$NON-NLS-1$
writer.value(unsatisfied[i].getRequirement().isOptional() );
writer.endObject();
}
writer.endArray();
}
}
writer.endObject();
}
private void toJSON( final JSONWriter writer, final Property[] props ) throws IOException
{
writer.object();
for ( int i = 0; props != null && i < props.length; i++ )
{
writer.key(props[i].getName());
writer.value(props[i].getValue());
}
writer.endObject();
}
}