/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2012 Servoy BV
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.
This program 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program; if not, see http://www.gnu.org/licenses or write to the Free
Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
package com.servoy.extension.install;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.servoy.extension.IExtensionProvider;
import com.servoy.extension.IFileBasedExtensionProvider;
import com.servoy.extension.IMessageProvider;
import com.servoy.extension.Message;
import com.servoy.extension.MessageKeeper;
import com.servoy.extension.dependency.ILibVersionChooser;
import com.servoy.extension.dependency.LibChoice;
import com.servoy.extension.dependency.TrackableLibDependencyDeclaration;
import com.servoy.extension.install.LibActivationHandler.LibActivation;
import com.servoy.extension.parser.EXPParser;
import com.servoy.extension.parser.FullDependencyMetadata;
import com.servoy.extension.parser.FullLibDependencyDeclaration;
import com.servoy.extension.parser.IEXPParserPool;
/**
* Takes in a list of lib choices, a lib version chooser and a lib activation handler, and activates for each choice the lib version chosen by the chooser.
* @author acostescu
*/
public class LibChoiceHandler implements IMessageProvider
{
protected IEXPParserPool parserPool;
protected IExtensionProvider extensionProvider; // can be null in case of uninstall
protected IFileBasedExtensionProvider installedExtensionsProvider;
protected MessageKeeper messages = new MessageKeeper();
protected List<LibActivation> activations = new ArrayList<LibActivation>();
public LibChoiceHandler(IFileBasedExtensionProvider installedExtensionsProvider, IExtensionProvider extensionProvider, IEXPParserPool parserPool)
{
this.installedExtensionsProvider = installedExtensionsProvider;
this.extensionProvider = extensionProvider;
this.parserPool = parserPool;
}
/**
* Chooses the lib versions that will get activated for choices.
* This MUST be called BEFORE the actuall install/uninstall/replace process executes, so while any uninstalled extensions are still available (installed),
* because access is needed to them for getting the uninstalledLibDependencies file paths.
* @param libChoices the lib choices to be made.
* @param libVersionChooser the chooser to apply to each choice.
*/
public void prepareChoices(LibChoice[] libChoices, ILibVersionChooser libVersionChooser)
{
activations.clear();
for (LibChoice choice : libChoices)
{
TrackableLibDependencyDeclaration chosenOne = libVersionChooser.chooseLibDeclaration(choice);
List<FullLibDependencyDeclaration> shovedLibs = new ArrayList<FullLibDependencyDeclaration>();
List<FullLibDependencyDeclaration> uninstalledLibs = null;
for (TrackableLibDependencyDeclaration ldd : choice.libDependencies)
{
if (chosenOne != ldd) shovedLibs.add(getFullDependencyDeclaration(ldd));
}
if (choice.uninstalledLibDependencies != null)
{
uninstalledLibs = new ArrayList<FullLibDependencyDeclaration>();
for (TrackableLibDependencyDeclaration ldd : choice.uninstalledLibDependencies)
{
uninstalledLibs.add(getFullDependencyDeclaration(ldd));
}
}
activations.add(new LibActivation(getFullDependencyDeclaration(chosenOne), getEXPFile(chosenOne),
shovedLibs.toArray(new FullLibDependencyDeclaration[shovedLibs.size()]), uninstalledLibs != null
? uninstalledLibs.toArray(new FullLibDependencyDeclaration[uninstalledLibs.size()]) : null));
}
}
/**
* Gives the prepared choices to the libActivationHandler for actual activation/deactivation of lib versions.
* This MUST be called AFTER the actuall install/uninstall/replace process executes, to make sure any herein activated lib version is
* not then deleted by that process (more then one extension/version could install the lib in the same path).
* @param libActivationHandler the handles the activations.
*/
public void handlePreparedChoices(LibActivationHandler libActivationHandler)
{
libActivationHandler.activateLibVersions(activations.toArray(new LibActivation[activations.size()]));
}
protected File getEXPFile(TrackableLibDependencyDeclaration tldd)
{
File f = null;
if (tldd.declaringExtensionInstalled)
{
f = installedExtensionsProvider.getEXPFile(tldd.declaringExtensionId, tldd.declaringExtensionVersion, null);
}
else if (extensionProvider != null)
{
f = extensionProvider.getEXPFile(tldd.declaringExtensionId, tldd.declaringExtensionVersion, null);
}
return f;
}
protected FullLibDependencyDeclaration getFullDependencyDeclaration(TrackableLibDependencyDeclaration tldd)
{
FullLibDependencyDeclaration result = null;
EXPParser parser = parserPool != null ? parserPool.getOrCreateParser(getEXPFile(tldd)) : new EXPParser(getEXPFile(tldd));
FullDependencyMetadata dmd = parser.parseDependencyInfo();
messages.addAll(parser.getMessages());
parser.clearMessages();
if (dmd != null)
{
for (FullLibDependencyDeclaration fldd : dmd.getLibDependencies())
{
if (fldd.id.equals(tldd.id) && fldd.version.equals(tldd.version))
{
result = fldd;
break;
}
}
}
if (result == null)
{
// should never happen
messages.addError("Cannot find full lib dependency declaration. Internal error."); //$NON-NLS-1$
}
return result;
}
public Message[] getMessages()
{
return messages.getMessages();
}
public void clearMessages()
{
messages.clearMessages();
}
}