blob: c7f7097fe749fbeaa5a240a3bcdd3b3758d766ed [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.netbeans.modules.autoupdate.ui;
import java.awt.Image;
import java.text.Collator;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.autoupdate.OperationContainer;
import org.netbeans.api.autoupdate.OperationContainer.OperationInfo;
import org.netbeans.api.autoupdate.OperationSupport;
import org.netbeans.api.autoupdate.UpdateElement;
import org.netbeans.api.autoupdate.UpdateManager;
import org.netbeans.api.autoupdate.UpdateUnit;
import org.netbeans.modules.autoupdate.ui.UnitCategoryTableModel.Type;
import org.openide.modules.SpecificationVersion;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
/**
*
* @author Jiri Rechtacek, Radek Matous
*/
public abstract class Unit {
UpdateUnit updateUnit = null;
private boolean isVisible;
private String filter;
private String categoryName;
static final Logger log = Logger.getLogger (Unit.class.getName ());
private String displayDate = null;
protected abstract UpdateElement getRelevantElement ();
public abstract boolean isMarked ();
public abstract void setMarked (boolean marked);
public abstract int getCompleteSize ();
Unit (String categoryName) {
this.categoryName = categoryName;
}
public abstract UnitCategoryTableModel.Type getModelType();
public void initState() {
if (UnitCategoryTableModel.isMarkedAsDefault(getModelType())) {
if (!isMarked() && canBeMarked()) {
setMarked(true);
}
}
}
public String getCategoryName () {
return categoryName;
}
public boolean canBeMarked () {
RequestProcessor.Task t = PluginManagerUI.getRunningTask ();
return t == null || t.isFinished ();
}
public String getDisplayName () {
return getRelevantElement ().getDisplayName ();
}
public final boolean isVisible (final String filter) {
if (this.filter != null && this.filter.equals (filter)) {
return isVisible;
}
this.filter = filter;
isVisible = filter.length () == 0;
if (isVisible) {
return isVisible;
}
Iterable<String> iterable = details ();
for (String detail : iterable) {
isVisible = detail.toLowerCase ().contains (filter);
if (isVisible) {
break;
}
}
return isVisible;
}
private Iterable<String> details () {
Iterable<String> retval = new Iterable<String>(){
@Override
public Iterator<String> iterator () {
return new Iterator<String>() {
int step = 0;
@Override
public boolean hasNext () {
return step <= 6;
}
@Override
public String next () {
String next = null;
switch(step++) {
case 0:
next = getDisplayName ();break;
case 1:
next = getCategoryName ();break;
case 2:
next = getDescription ();break;
case 3:
next = updateUnit.getCodeName ();break;
case 4:
next = getDisplayVersion ();break;
case 5:
next = getAuthor ();break;
case 6:
next = getHomepage ();break;
}
return next != null ? next : "";//NOI18N
}
@Override
public void remove () {
throw new UnsupportedOperationException ("Not supported yet.");
}
};
}
};
return retval;
}
public String getFilter() {
return filter;
}
public String getDescription () {
return getRelevantElement ().getDescription ();
}
public String getNotification () {
return getRelevantElement ().getNotification ();
}
public String getAuthor () {
return getRelevantElement ().getAuthor ();
}
public String getHomepage () {
return getRelevantElement ().getHomepage ();
}
public String getSource () {
return getRelevantElement ().getSource ();
}
public String getDisplayVersion () {
return getRelevantElement ().getSpecificationVersion ();
}
public String getDisplayDate () {
if (displayDate == null) {
String sd = getRelevantElement ().getDate ();
if (sd != null) {
try {
Date d = Utilities.DATE_FORMAT.parse (sd);
displayDate = DateFormat.getDateInstance (DateFormat.SHORT, Locale.getDefault ()).format (d);
} catch (ParseException pe) {
log.log (Level.INFO, "ParseException while parsing date " + sd, pe);
}
}
}
return displayDate;
}
public static int compareDisplayNames (Unit unit1, Unit unit2) {
//if (!Utilities.modulesOnly()) {
return Utilities.getCategoryComparator().compare(unit1.getDisplayName(), unit2.getDisplayName());
//}
//return Collator.getInstance().compare(unit1.getDisplayName(), unit2.getDisplayName());
}
public static int compareCategories (Unit unit1, Unit unit2) {
return Utilities.getCategoryComparator ().compare (unit1.getCategoryName (), unit2.getCategoryName ());
}
public static int compareSimpleFormatDates (Unit u1, Unit u2) {
if (u1.getRelevantElement ().getDate () == null) {
if (u2.getRelevantElement ().getDate () == null) {
return 0;
} else {
return -1;
}
} else if (u2.getRelevantElement ().getDate () == null) {
return 1;
}
Date d1;
Date d2;
try {
d1 = Utilities.DATE_FORMAT.parse (u1.getRelevantElement ().getDate ());
} catch (ParseException pe) {
log.log (Level.INFO, "ParseException while parsing date " + u1.getRelevantElement ().getDate (), pe);
return -1;
}
try {
d2 = Utilities.DATE_FORMAT.parse (u2.getRelevantElement ().getDate ());
} catch (ParseException pe) {
log.log (Level.INFO, "ParseException while parsing date " + u2.getRelevantElement ().getDate (), pe);
return 1;
}
return d1.compareTo (d2);
}
public static int compareDisplayVersions (Unit unit1, Unit unit2) {
if (unit1.getDisplayVersion () == null) {
if (unit2.getDisplayVersion () == null) {
return 0;
} else {
return -1;
}
} else if (unit2.getDisplayVersion () == null) {
return 1;
}
return new SpecificationVersion (unit1.getDisplayVersion ()).compareTo (new SpecificationVersion (unit2.getDisplayVersion ()));
}
public static int compareCompleteSizes (Unit unit1, Unit unit2) {
return Integer.valueOf (unit1.getCompleteSize ()).compareTo (unit2.getCompleteSize ());
}
public static class Installed extends Unit {
private UpdateElement installEl = null;
private UpdateElement backupEl = null;
private boolean uninstallationAllowed;
private boolean deactivationAllowed;
private boolean activationAllowed;
public static boolean isOperationAllowed (UpdateUnit uUnit, UpdateElement element, OperationContainer<OperationSupport> container) {
return container.canBeAdded (uUnit, element);
}
public Installed (UpdateUnit unit, String categoryName) {
super (categoryName);
this.updateUnit = unit;
if (unit.getInstalled () == null && unit.isPending ()) {
this.installEl = unit.getAvailableUpdates ().get (0);
assert installEl != null : "Pending UpdateUnit " + unit + " has UpdateElement for update.";
} else {
this.installEl = unit.getInstalled ();
assert installEl != null : "Installed UpdateUnit " + unit + " has Installed UpdateElement.";
}
this.backupEl = unit.getBackup ();
OperationContainer<OperationSupport> container;
if (UpdateManager.TYPE.CUSTOM_HANDLED_COMPONENT == updateUnit.getType ()) {
container = Containers.forCustomUninstall ();
} else {
container = Containers.forUninstall ();
}
uninstallationAllowed = isOperationAllowed (this.updateUnit, installEl, container);
deactivationAllowed = isOperationAllowed (this.updateUnit, installEl, Containers.forDisable());
activationAllowed = isOperationAllowed (this.updateUnit, installEl, Containers.forEnable());
initState();
}
public boolean isUninstallAllowed() {
return uninstallationAllowed;
}
public boolean isDeactivationAllowed() {
return deactivationAllowed;
}
public boolean isActivationAllowed() {
return activationAllowed;
}
@Override
public boolean isMarked () {
boolean uninstallMarked;
OperationContainer container;
if (UpdateManager.TYPE.CUSTOM_HANDLED_COMPONENT == updateUnit.getType ()) {
container = Containers.forCustomUninstall ();
} else {
container = Containers.forUninstall ();
}
uninstallMarked = container.contains (installEl);
boolean deactivateMarked = Containers.forDisable().contains (installEl);
boolean activateMarked = Containers.forEnable().contains (installEl);
return deactivateMarked || uninstallMarked || activateMarked;
}
@Override
public void setMarked (boolean marked) {
assert marked != isMarked ();
if (isUninstallAllowed()) {
OperationContainer container;
if (UpdateManager.TYPE.CUSTOM_HANDLED_COMPONENT == updateUnit.getType ()) {
container = Containers.forCustomUninstall ();
} else {
container = Containers.forUninstall ();
}
if (marked) {
container.add (updateUnit, installEl);
} else {
container.remove (installEl);
}
}
if (isDeactivationAllowed()) {
OperationContainer container = Containers.forDisable();
if (marked) {
container.add (updateUnit, installEl);
} else {
container.remove (installEl);
}
} else if (isActivationAllowed()) {
OperationContainer container = Containers.forEnable();
if (marked) {
container.add (updateUnit, installEl);
} else {
container.remove (installEl);
}
}
}
public static int compareEnabledState (Unit u1, Unit u2) {
if (u1 instanceof Unit.Installed && u2 instanceof Unit.Installed) {
Unit.Installed unit1 = (Unit.Installed )u1;
Unit.Installed unit2 = (Unit.Installed )u2;
final int retval = Boolean.valueOf(unit1.getRelevantElement().isEnabled()).compareTo(unit2.getRelevantElement().isEnabled());
return (retval == 0) ? Boolean.valueOf(unit1.updateUnit.isPending()).compareTo(unit2.updateUnit.isPending()) : retval;
}
return Unit.compareDisplayVersions (u1, u2);
}
public static int compareInstalledVersions (Unit u1, Unit u2) {
if (u1 instanceof Unit.Installed && u2 instanceof Unit.Installed) {
Unit.Installed unit1 = (Unit.Installed )u1;
Unit.Installed unit2 = (Unit.Installed )u2;
if (unit1.getInstalledVersion () == null) {
if (unit2.getInstalledVersion () == null) {
return 0;
} else {
return -1;
}
} else if (unit2.getInstalledVersion () == null) {
return 1;
}
return new SpecificationVersion (unit1.getInstalledVersion ()).compareTo (new SpecificationVersion (unit2.getInstalledVersion ()));
}
return Unit.compareDisplayVersions (u1, u2);
}
@Override
public boolean canBeMarked () {
return super.canBeMarked () && (isDeactivationAllowed() || isUninstallAllowed() || isActivationAllowed());
}
public String getInstalledVersion () {
return installEl.getSpecificationVersion ();
}
public String getBackupVersion () {
return backupEl == null ? "-" : backupEl.getSpecificationVersion ();
}
public Integer getMyRating () {
return null;
}
@Override
public UpdateElement getRelevantElement () {
return installEl;
}
@Override
public int getCompleteSize () {
return -1;
}
@Override
public Type getModelType() {
return UnitCategoryTableModel.Type.INSTALLED;
}
}
public static class CompoundUpdate extends Unit.Update {
private TreeSet<UpdateUnit> internalUpdates;
public CompoundUpdate(UpdateUnit updateUnit, String categoryName) {
super(updateUnit, false, categoryName);
}
public TreeSet<UpdateUnit> getUpdateUnits() {
if (internalUpdates == null) {
internalUpdates = new TreeSet<UpdateUnit>(new Comparator<UpdateUnit>() {
@Override
public int compare(UpdateUnit uu1, UpdateUnit uu2) {
UpdateElement ue1 = uu1.getInstalled() != null ? uu1.getInstalled() : uu1.getAvailableUpdates().get(0);
UpdateElement ue2 = uu2.getInstalled() != null ? uu2.getInstalled() : uu2.getAvailableUpdates().get(0);
return ue1.getDisplayName().compareTo(ue2.getDisplayName());
}
});
}
return internalUpdates;
}
public UpdateElement getRealUpdate() {
return hasInternalsOnly() ? null : updateUnit.getAvailableUpdates().get(0);
}
@Override
public UpdateElement getRelevantElement() {
return hasInternalsOnly() ? updateUnit.getInstalled() : updateUnit.getAvailableUpdates().get(0);
}
@Override
public boolean isMarked() {
OperationContainer container = Containers.forUpdate ();
for(UpdateUnit invisible : getUpdateUnits()) {
if(!container.contains(invisible.getAvailableUpdates().get(0))) {
return false;
}
}
if (! hasInternalsOnly()) {
if (! container.contains(getRelevantElement())) {
return false;
}
}
return true;
}
@Override
public String getAvailableVersion () {
if (updateUnit.getAvailableUpdates().isEmpty()) {
return getInstalledVersion() + " " + getBundle("Unit_InternalUpdates_Version");
} else {
return super.getAvailableVersion();
}
}
@Override
public void setMarked(boolean marked) {
if (marked == isMarked()) {
log.info("Not necessary mark " + this + " as " + marked + " if it'is marked as " + isMarked());
return ;
}
OperationContainer container = Containers.forUpdate();
for (UpdateUnit invisible : getUpdateUnits()) {
if (marked) {
if (container.canBeAdded(invisible, invisible.getAvailableUpdates().get(0))) {
container.add(invisible, invisible.getAvailableUpdates().get(0));
}
} else {
container.remove(invisible.getAvailableUpdates().get(0));
}
}
if (! hasInternalsOnly()) {
if (marked) {
if (container.canBeAdded(updateUnit, getRelevantElement())) {
container.add(updateUnit, getRelevantElement());
}
} else {
container.remove(getRelevantElement());
}
}
}
@Override
public int getCompleteSize() {
if (size == -1) {
size = 0;
for (UpdateUnit u : getUpdateUnits()) {
size += u.getAvailableUpdates().get(0).getDownloadSize();
}
}
return size;
}
@Override
public String getSize () {
return Utilities.getDownloadSizeAsString (getCompleteSize());
}
@Override
public Type getModelType() {
return Type.UPDATE;
}
private boolean hasInternalsOnly() {
return updateUnit.getAvailableUpdates().isEmpty();
}
}
public static class Update extends Unit {
private UpdateElement installEl = null;
private UpdateElement updateEl = null;
private boolean isNbms;
protected int size = -1;
public Update (UpdateUnit unit, boolean isNbms, String categoryName) {
super (categoryName);
this.isNbms = isNbms;
this.updateUnit = unit;
this.installEl = unit.getInstalled ();
assert installEl != null : "Updateable UpdateUnit " + unit + " has Installed UpdateElement.";
if(unit.getAvailableUpdates().size() > 0) {
this.updateEl = unit.getAvailableUpdates ().get (0);
assert updateEl != null : "Updateable UpdateUnit " + unit + " has UpdateElement for update.";
}
initState();
}
@Override
public boolean isMarked () {
OperationContainer container;
if (isNbms) {
container = Containers.forUpdateNbms ();
} else if (UpdateManager.TYPE.CUSTOM_HANDLED_COMPONENT == updateUnit.getType ()) {
container = Containers.forCustomInstall ();
} else {
container = Containers.forUpdate ();
}
return container.contains (updateEl);
}
@Override
public void setMarked (boolean marked) {
if (marked == isMarked()) {
return;
}
OperationContainer container;
if (isNbms) {
container = Containers.forUpdateNbms ();
} else if (UpdateManager.TYPE.CUSTOM_HANDLED_COMPONENT == updateUnit.getType ()) {
container = Containers.forCustomInstall ();
} else {
container = Containers.forUpdate ();
}
if (marked) {
try {
container.add (updateUnit, updateEl);
} catch (IllegalArgumentException ex) {
log.log(Level.WARNING, ex.getMessage());
}
} else {
container.remove (updateEl);
}
}
public static int compareInstalledVersions (Unit u1, Unit u2) {
if (u1 instanceof Unit.Update && u2 instanceof Unit.Update) {
Unit.Update unit1 = (Unit.Update)u1;
Unit.Update unit2 = (Unit.Update)u2;
return new SpecificationVersion (unit1.getInstalledVersion ()).compareTo (new SpecificationVersion (unit2.getInstalledVersion ()));
}
return Unit.compareDisplayVersions (u1, u2);
}
public static int compareAvailableVersions (Unit u1, Unit u2) {
if (u1 instanceof Unit.Update && u2 instanceof Unit.Update) {
Unit.Update unit1 = (Unit.Update)u1;
Unit.Update unit2 = (Unit.Update)u2;
return new SpecificationVersion (unit1.getAvailableVersion ()).compareTo (new SpecificationVersion (unit2.getAvailableVersion ()));
}
return Unit.compareDisplayVersions (u1, u2);
}
public String getInstalledVersion () {
return installEl.getSpecificationVersion ();
}
public String getAvailableVersion () {
return getRelevantElement().getSpecificationVersion ();
}
public String getSize () {
return Utilities.getDownloadSizeAsString (updateEl.getDownloadSize ());
}
@Override
public UpdateElement getRelevantElement () {
return updateEl;
}
@Override
public int getCompleteSize () {
if (size == -1) {
size = 0;
OperationContainer<OperationSupport> c = OperationContainer.createForDirectUpdate ();
OperationInfo<OperationSupport> i = c.add (getRelevantElement ());
Set<UpdateElement> elems = i.getRequiredElements ();
for (UpdateElement el : elems) {
size += el.getDownloadSize ();
}
size += getRelevantElement ().getDownloadSize ();
c.removeAll ();
}
return size;
}
@Override
public Type getModelType() {
return (isNbms) ? UnitCategoryTableModel.Type.LOCAL : UnitCategoryTableModel.Type.UPDATE;
}
}
public static class Available extends Unit {
private UpdateElement updateEl = null;
private boolean isNbms;
private int size = -1;
public Available (UpdateUnit unit, boolean isNbms,String categoryName) {
super (categoryName);
this.isNbms = isNbms;
this.updateUnit = unit;
this.updateEl = unit.getAvailableUpdates ().get (0);
assert updateEl != null : "Updateable UpdateUnit " + unit + " has UpdateElement for update.";
initState();
}
@Override
public boolean isMarked () {
OperationContainer container;
if (isNbms) {
container = Containers.forAvailableNbms();
} else if (UpdateManager.TYPE.CUSTOM_HANDLED_COMPONENT == updateUnit.getType ()) {
container = Containers.forCustomInstall ();
} else {
container = Containers.forAvailable ();
}
return container.contains (updateEl);
}
@Override
public void setMarked (boolean marked) {
assert marked != isMarked ();
OperationContainer container;
if (isNbms) {
container = Containers.forAvailableNbms();
} else if (UpdateManager.TYPE.CUSTOM_HANDLED_COMPONENT == updateUnit.getType ()) {
container = Containers.forCustomInstall ();
} else {
container = Containers.forAvailable ();
}
if (marked) {
try {
container.add (updateUnit, updateEl);
} catch (IllegalArgumentException iae) {
log.warning(iae.getMessage());
}
} else {
container.remove (updateEl);
}
}
public static int compareAvailableVersion (Unit u1, Unit u2) {
if (u1 instanceof Unit.Available && u2 instanceof Unit.Available) {
Unit.Available unit1 = (Unit.Available)u1;
Unit.Available unit2 = (Unit.Available)u2;
return new SpecificationVersion (unit1.getAvailableVersion ()).compareTo (new SpecificationVersion (unit2.getAvailableVersion ()));
}
return Unit.compareDisplayVersions (u1, u2);
}
public static int compareSourceCategories(Unit u1, Unit u2) {
if (u1 instanceof Unit.Available && u2 instanceof Unit.Available) {
Unit.Available unit1 = (Unit.Available)u1;
Unit.Available unit2 = (Unit.Available)u2;
return Collator.getInstance().compare(unit1.getSourceDescription(), unit2.getSourceDescription());
}
throw new IllegalStateException();
}
public String getAvailableVersion () {
return updateEl.getSpecificationVersion ();
}
public Integer getMyRating () {
return null;
}
public String getSize () {
return Utilities.getDownloadSizeAsString (updateEl.getDownloadSize ());
}
@Override
public UpdateElement getRelevantElement () {
return updateEl;
}
@Override
public int getCompleteSize () {
if (size == -1) {
size = 0;
OperationContainer<OperationSupport> c = OperationContainer.createForDirectInstall ();
OperationInfo<OperationSupport> i = c.add (getRelevantElement ());
Set<UpdateElement> elems = i.getRequiredElements ();
for (UpdateElement el : elems) {
size += el.getDownloadSize ();
}
size += getRelevantElement ().getDownloadSize ();
c.removeAll ();
}
return size;
}
@Override
public Type getModelType() {
return (isNbms) ? UnitCategoryTableModel.Type.LOCAL : UnitCategoryTableModel.Type.AVAILABLE;
}
public Image getSourceIcon() {
return updateEl.getSourceIcon();
}
public String getSourceDescription() {
return updateEl.getSourceDescription();
}
}
private static String getBundle (String key) {
return NbBundle.getMessage (Unit.class, key);
}
@Override
public String toString() {
return super.toString() + "[" + getDisplayName() + "]";
}
}