blob: 643032363b51c2ed78cd7ef86bb9404da5153aa6 [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed 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 com.intellij.android.designer.model;
import com.intellij.android.designer.model.morphing.RelativeLayout;
import com.intellij.designer.model.MetaModel;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.RadLayout;
import com.intellij.openapi.application.ApplicationManager;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class ComponentMorphingTool {
protected final RadViewComponent myOldComponent;
protected final RadViewComponent myNewComponent;
public ComponentMorphingTool(RadViewComponent oldComponent,
RadViewComponent newComponent,
MetaModel newModel,
@Nullable RadLayout newLayout) throws Exception {
myOldComponent = oldComponent;
myNewComponent = newComponent;
newComponent.setMetaModel(newModel);
if (newLayout != null) {
newComponent.setLayout(newLayout);
}
if (newComponent != oldComponent) {
RadComponent parent = oldComponent.getParent();
newComponent.setParent(parent);
List<RadComponent> parentChildren = parent.getChildren();
parentChildren.set(parentChildren.indexOf(oldComponent), newComponent);
newComponent.setTag(oldComponent.getTag());
convertChildren();
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
convertTag();
myNewComponent.getTag().setName(myNewComponent.getMetaModel().getTag());
}
});
PropertyParser propertyParser = RadModelBuilder.getPropertyParser(newComponent);
if (propertyParser != null) {
propertyParser.load(newComponent);
loadChildProperties(propertyParser);
}
}
protected void convertChildren() throws Exception {
List<RadComponent> oldChildren = myOldComponent.getChildren();
myNewComponent.getChildren().addAll(oldChildren);
for (RadComponent childComponent : oldChildren) {
childComponent.setParent(myNewComponent);
}
}
protected void convertTag() {
}
protected void loadChildProperties(PropertyParser propertyParser) throws Exception {
for (RadComponent childComponent : myNewComponent.getChildren()) {
propertyParser.load((RadViewComponent)childComponent);
}
}
public RadViewComponent result() {
return myNewComponent;
}
public static RadViewComponent convert(RadViewComponent component, MetaModel target) throws Exception {
ClassLoader classLoader = ComponentMorphingTool.class.getClassLoader();
Class<?> sourceConverterClass = classLoader.loadClass(
"com.intellij.android.designer.model.morphing." + component.getMetaModel().getTag());
Object sourceConverter = sourceConverterClass.newInstance();
try {
Method method = sourceConverterClass.getMethod(target.getTag(), RadViewComponent.class, MetaModel.class);
return (RadViewComponent)method.invoke(sourceConverter, component, target);
}
catch (NoSuchMethodException e) {
if ("RelativeLayout".equals(target.getTag())) {
return RelativeLayout.RelativeLayout(component, target);
}
throw e;
}
}
}