/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.foundation.ie.action;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openflexo.foundation.FlexoEditor;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.action.FlexoAction;
import org.openflexo.foundation.action.FlexoActionType;
import org.openflexo.foundation.ie.IEObject;
import org.openflexo.foundation.ie.IEReusableComponent;
import org.openflexo.foundation.ie.IEWOComponent;
import org.openflexo.foundation.ie.cl.FlexoComponentFolder;
import org.openflexo.foundation.ie.cl.ReusableComponentDefinition;
import org.openflexo.foundation.ie.util.FolderType;
import org.openflexo.foundation.ie.widget.AbstractInnerTableWidget;
import org.openflexo.foundation.ie.widget.IEBlocWidget;
import org.openflexo.foundation.ie.widget.IEReusableWidget;
import org.openflexo.foundation.ie.widget.IESequenceTR;
import org.openflexo.foundation.ie.widget.IESequenceWidget;
import org.openflexo.foundation.ie.widget.IETabWidget;
import org.openflexo.foundation.ie.widget.IEWidget;
import org.openflexo.foundation.ie.widget.ITableRow;
import org.openflexo.foundation.ie.widget.ITableRowReusableWidget;
import org.openflexo.foundation.ie.widget.InnerBlocReusableWidget;
import org.openflexo.foundation.ie.widget.InnerBlocWidgetInterface;
import org.openflexo.foundation.ie.widget.InnerTableReusableWidget;
import org.openflexo.foundation.ie.widget.TopComponentReusableWidget;
import org.openflexo.foundation.rm.DuplicateResourceException;
import org.openflexo.foundation.rm.FlexoComponentResource;
import org.openflexo.foundation.rm.FlexoXMLStorageResource.SaveXMLResourceException;
import org.openflexo.foundation.rm.SaveResourceException;
import org.openflexo.foundation.rm.SaveResourcePermissionDeniedException;
public class MakePartialComponent extends FlexoAction<MakePartialComponent, IEWidget, IEWidget> {
private static final Logger logger = Logger.getLogger(MakePartialComponent.class.getPackage().getName());
private IEReusableWidget reusableWidget;
public static FlexoActionType<MakePartialComponent, IEWidget, IEWidget> actionType = new FlexoActionType<MakePartialComponent, IEWidget, IEWidget>(
"make_partial_component", FlexoActionType.defaultGroup) {
/**
* Factory method
*/
@Override
public MakePartialComponent makeNewAction(IEWidget focusedObject, Vector<IEWidget> globalSelection, FlexoEditor editor) {
return new MakePartialComponent(focusedObject, globalSelection, editor);
}
@Override
public boolean isVisibleForSelection(IEWidget object, Vector<IEWidget> globalSelection) {
return !(object instanceof IETabWidget);
}
@Override
public boolean isEnabledForSelection(IEWidget object, Vector<IEWidget> globalSelection) {
return !(object instanceof IEReusableWidget);
}
};
static {
FlexoModelObject.addActionForClass(actionType, IEWidget.class);
}
private String _newComponentName;
private FlexoComponentFolder _newComponentFolder;
private FlexoComponentResource _newComponentResource;
MakePartialComponent(IEWidget focusedObject, Vector<IEWidget> globalSelection, FlexoEditor editor) {
super(actionType, focusedObject, globalSelection, editor);
}
public FlexoComponentFolder getNewComponentFolder() {
if (_newComponentFolder == null) {
_newComponentFolder = getFocusedObject().getProject().getFlexoComponentLibrary().getRootFolder()
.getFolderTyped(FolderType.PARTIAL_COMPONENT_FOLDER);
}
return _newComponentFolder;
}
public void setNewComponentFolder(FlexoComponentFolder newComponentFolder) {
_newComponentFolder = newComponentFolder;
}
public String getNewComponentName() {
return _newComponentName;
}
public void setNewComponentName(String newComponentName) {
_newComponentName = newComponentName;
}
public FlexoComponentResource getNewComponentResource() {
return _newComponentResource;
}
@Override
protected void doAction(Object context) {
if (getFocusedObject() != null) {
IEWidget widget = getFocusedObject();
if (logger.isLoggable(Level.FINE)) {
logger.fine("Make partial component from " + widget);
}
try {
_newComponentResource = makeItPartial(widget, getNewComponentName(), getNewComponentFolder());
} catch (DuplicateResourceException e) {
e.printStackTrace();
}
} else {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("No widget defined !");
}
}
}
public IEReusableComponent getComponent() {
return comp;
}
private IEReusableComponent comp;
private FlexoComponentResource makeItPartial(IEWidget widget, String newPartialComponentName, FlexoComponentFolder folder)
throws DuplicateResourceException {
IEWOComponent woComponent = widget.getWOComponent();
IEObject parent = widget.getParent();
Vector<IEWidget> widgets = new Vector<IEWidget>();
widgets.add(widget);
int minIndex = widget.getIndex();
int maxIndex = widget.getIndex();
if (getGlobalSelection() != null) {
for (IEWidget w : getGlobalSelection()) {
if (w.getParent() == parent) {
widgets.add(w);
minIndex = Math.min(minIndex, w.getIndex());
maxIndex = Math.max(maxIndex, w.getIndex());
}
}
if (maxIndex - minIndex + 1 != widgets.size()) {
widgets.clear();
widgets.add(widget);
}
}
Collections.sort(widgets, new Comparator<IEWidget>() {
@Override
public int compare(IEWidget o1, IEWidget o2) {
return o1.getIndex() - o2.getIndex();
}
});
// first create the component definition in the library
ReusableComponentDefinition compDef = new ReusableComponentDefinition(newPartialComponentName, folder.getComponentLibrary(),
folder, widget.getProject());
FlexoComponentResource compRes = compDef.getComponentResource();// Creates the resource
comp = new IEReusableComponent(compDef, widget.getProject());
comp.setFlexoResource(compRes);
for (IEWidget w : widgets) {
w.setWOComponent(comp);
comp.getRootSequence().addToInnerWidgets(w);
}
compRes.setResourceData(comp);
try {
compRes.saveResourceData();
} catch (SaveXMLResourceException e1) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("ERROR while saving partial component");
}
e1.printStackTrace();
} catch (SaveResourcePermissionDeniedException e1) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("ERROR while saving partial component. Please check permissions");
}
e1.printStackTrace();
} catch (SaveResourceException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("ERROR while saving partial component");
}
e.printStackTrace();
}
// 5. create a new ReusableWidget to store the ComponentInstance
if (widget instanceof InnerBlocWidgetInterface && parent instanceof IEBlocWidget) {
reusableWidget = new InnerBlocReusableWidget(woComponent, compDef, (IEBlocWidget) parent, widget.getProject());
} else if (widget instanceof AbstractInnerTableWidget && parent instanceof IEWidget) {
reusableWidget = new InnerTableReusableWidget(woComponent, compDef, (IEWidget) parent, widget.getProject());
} else if (widget.isTopComponent() && parent instanceof IESequenceWidget) {
reusableWidget = new TopComponentReusableWidget(woComponent, compDef, (IESequenceWidget) parent, widget.getProject());
} else if (widget instanceof IESequenceTR && parent instanceof IESequenceTR) {
reusableWidget = new ITableRowReusableWidget(woComponent, compDef, parent, widget.getProject());
}
// 6. Insert the reusableWidget in its parent
if (reusableWidget != null) {
if (reusableWidget instanceof InnerBlocReusableWidget && parent instanceof IEBlocWidget) {
((IEBlocWidget) parent).replaceWidgetByReusable(widget, (InnerBlocReusableWidget) reusableWidget);
} else if (reusableWidget instanceof InnerTableReusableWidget || reusableWidget instanceof TopComponentReusableWidget) {
if (parent instanceof IESequenceWidget) {
for (IEWidget w : widgets) {
((IESequenceWidget) parent).removeFromInnerWidgets(w, false);
((IESequenceWidget) parent).insertElementAt(reusableWidget, minIndex);
}
}
} else if (reusableWidget instanceof ITableRowReusableWidget) {
((IESequenceTR) parent).replaceWidgetByReusable((ITableRow) widget, (ITableRowReusableWidget) reusableWidget);
((IESequenceTR) parent).htmlTable().setTRRowIndex();
}
}
return compRes;
}
public IEReusableWidget getReusableWidget() {
return reusableWidget;
}
}