| /* |
| * 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; |
| } |
| } |
| } |