/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.ant.bnd.spring;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Annotation;
import aQute.bnd.osgi.ClassDataCollector;
import aQute.bnd.osgi.Clazz;
import aQute.bnd.osgi.Descriptors;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Resource;
import aQute.bnd.osgi.WriteResource;
import aQute.bnd.service.AnalyzerPlugin;
import aQute.lib.io.IO;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/**
* @author Miguel Pastor
*/
public class SpringDependencyAnalyzerPlugin implements AnalyzerPlugin {
@Override
public boolean analyzeJar(Analyzer analyzer) throws Exception {
String property = analyzer.getProperty("-liferay-spring-dependency");
Parameters parameters = analyzer.parseHeader(property);
if (parameters.isEmpty()) {
return false;
}
Jar jar = analyzer.getJar();
Collection<Clazz> classes = analyzer.getClasses();
Set<String> serviceReferences = new TreeSet<String>();
for (String key : parameters.keySet()) {
ServiceReferenceCollector serviceReferenceCollector =
new ServiceReferenceCollector(key);
for (Clazz clazz : classes) {
clazz.parseClassFileWithCollector(serviceReferenceCollector);
}
serviceReferences.addAll(
serviceReferenceCollector.getServiceReferences());
}
String releaseInfo = getReleaseInfo(analyzer);
if (!releaseInfo.equals("")) {
serviceReferences.add(releaseInfo);
}
jar.putResource(
"OSGI-INF/context/context.dependencies",
new ContextDependencyWriter(analyzer, serviceReferences));
return false;
}
protected String getReleaseInfo(Analyzer analyzer) {
String property = analyzer.getProperty("Liferay-Require-SchemaVersion");
if (property == null) {
return "";
}
StringBuffer sb = new StringBuffer(6);
sb.append("com.liferay.portal.kernel.model.Release ");
sb.append("(&(release.bundle.symbolic.name=");
Map.Entry<String, Attrs> entry = analyzer.getBundleSymbolicName();
sb.append(entry.getKey());
sb.append(")(release.schema.version=");
sb.append(property);
sb.append("))");
return sb.toString();
}
private static class ContextDependencyWriter extends WriteResource {
public ContextDependencyWriter(
Analyzer analyzer, Set<String> serviceReferences) {
_serviceReferences = serviceReferences;
Jar jar = analyzer.getJar();
_resource = jar.getResource("META-INF/spring/context.dependencies");
}
@Override
public long lastModified() {
return 0;
}
@Override
public void write(OutputStream outputStream) throws Exception {
PrintWriter printWriter = new PrintWriter(
new OutputStreamWriter(outputStream, "UTF-8"));
String contextDependencies = "";
if (_resource != null) {
contextDependencies = IO.collect(
_resource.openInputStream(), "UTF-8");
}
if (!contextDependencies.equals("")) {
printWriter.println(contextDependencies);
}
for (String serviceReference : _serviceReferences) {
printWriter.println(serviceReference);
}
printWriter.flush();
}
private final Resource _resource;
private final Set<String> _serviceReferences;
}
private static class ServiceReferenceCollector extends ClassDataCollector {
public ServiceReferenceCollector(String annotationFQN) {
_annotationFQN = annotationFQN;
}
@Override
public void annotation(Annotation annotation) throws Exception {
Descriptors.TypeRef typeRef = annotation.getName();
String fqn = typeRef.getFQN();
if (!_annotationFQN.equals(fqn)) {
return;
}
Descriptors.Descriptor descriptor = _fieldDef.getDescriptor();
typeRef = descriptor.getType();
fqn = typeRef.getFQN();
Object filterString = annotation.get("filterString");
if (filterString != null) {
fqn += " " + filterString;
}
_serviceReferences.add(fqn);
}
@Override
public void field(Clazz.FieldDef fieldDef) {
_fieldDef = fieldDef;
}
public Set<String> getServiceReferences() {
return _serviceReferences;
}
private final String _annotationFQN;
private Clazz.FieldDef _fieldDef;
private final Set<String> _serviceReferences = new HashSet<String>();
}
}