001    /*
002      Copyright (C) 2002 Laurent Martelli <laurent@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public
015      License along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
017      USA */
018    
019    package org.objectweb.jac.ide;
020    
021    // Look and feels
022    
023    import java.awt.Component;
024    import java.io.FileInputStream;
025    import java.io.FileOutputStream;
026    import java.io.IOException;
027    import java.util.Collection;
028    import java.util.Iterator;
029    import java.util.Vector;
030    import javax.swing.LookAndFeel;
031    import javax.swing.SwingUtilities;
032    import javax.swing.UIManager;
033    import javax.swing.UnsupportedLookAndFeelException;
034    import org.apache.log4j.Logger;
035    import org.objectweb.jac.aspects.cache.CacheAC;
036    import org.objectweb.jac.aspects.gui.CustomizedDisplay;
037    import org.objectweb.jac.aspects.gui.ResourceManager;
038    import org.objectweb.jac.core.ACManager;
039    import org.objectweb.jac.core.Collaboration;
040    import org.objectweb.jac.core.ObjectRepository;
041    import org.objectweb.jac.core.rtti.ClassRepository;
042    import org.objectweb.jac.core.rtti.FieldItem;
043    import org.objectweb.jac.lib.Attachment;
044    import org.objectweb.jac.util.File;
045    import org.objectweb.jac.util.Predicate;
046    import org.objectweb.jac.util.Streams;
047    
048    /**
049     * Gui methods for the menus.
050     */
051    public class Gui {
052        static final Logger logger = Logger.getLogger("umlaf.gui");
053    
054        protected static void setLookAndFeel(LookAndFeel look) 
055            throws UnsupportedLookAndFeelException 
056        {
057            Object d = Collaboration.get().getAttribute("Gui.display");
058            if (d instanceof CustomizedDisplay) {
059                CustomizedDisplay display = (CustomizedDisplay)d;
060                UIManager.setLookAndFeel(look);
061                Iterator i = display.getCustomizedViews().iterator();
062                while (i.hasNext()) {
063                    Object frame = i.next();
064                    if (frame instanceof Component) {
065                        SwingUtilities.updateComponentTreeUI((Component)frame);
066                    }
067                }
068            }
069          
070        }
071    
072        /**
073         * Gets the project an element belongs to
074         * @param element the element whose projet to return
075         */
076        protected static Project getProject(ModelElement element) {
077            Project project = null;
078            if (element instanceof Member) {
079                project = ((Member)element).getProject();
080            } else if (element instanceof Parameter) {
081                Method method = ((Parameter)element).getMethod();
082                if (method!=null)
083                    project = method.getProject();
084            } else if (element instanceof Class) {
085                return ((Class)element).getProject();
086            }
087            return project;
088        }
089    
090        /**
091         * Returns all types which belong to the same project as a
092         * given member.
093         * @param element the element
094         * @see #getAvailableClasses(ModelElement)
095         * @see #getMatchingTypes(ModelElement,String)
096         */
097        public static Collection getAvailableTypes(ModelElement element) {
098            Vector result = new Vector();
099            Project project = getProject(element);
100            Collection types = ObjectRepository.getObjects(
101                ClassRepository.get().getClass("org.objectweb.jac.ide.Type"));
102            Iterator it = types.iterator();
103            while (it.hasNext()) {
104                Type type = (Type)it.next();
105                if (((element instanceof Field) || (element instanceof Parameter)) && 
106                    type==Projects.types.resolveType("void"))
107                    continue;
108                if (!(type instanceof Class && project!=null &&
109                      ((Class)type).getProject()!=project)) {
110                    result.add(type);
111                }
112            }
113            return result;
114        }
115    
116        /**
117         * Returns types with a given short name
118         */
119        public static Collection getMatchingTypes(ModelElement element, final String search) {
120            Vector result = new Vector();
121            new Predicate() {
122                    public boolean apply(Object o) {
123                        return ((ModelElement)o).getName().compareToIgnoreCase(search)==0;
124                    }
125                }.filter(getAvailableTypes(element),result);
126            return result;
127        }
128    
129        /**
130         * Returns all classes which belong to the same project as a
131         * given member.
132         * @param element the element
133         * @see #getAvailableTypes(ModelElement)
134         * @see #getMatchingTypes(ModelElement,String)
135         */
136        public static Collection getAvailableClasses(ModelElement element) {
137            Project project = getProject(element);
138            return project.getClasses();
139        }
140    
141        public static void invalidateCache() {
142            CacheAC cacheAspect = (CacheAC)ACManager.getACM().getACFromFullName("ide.cache");
143            if (cacheAspect!=null)
144                cacheAspect.invalidateCache();
145            else
146                throw new RuntimeException("Could not find cache aspect \"ide.cache\"");
147        }
148    
149        public static void edit(Attachment attachment) 
150            throws IOException 
151        {
152            String editor = Projects.prefs.getExternalEditor();
153            if (editor!=null) {
154                new ExternalEditorThread(editor,attachment).start();            
155            } else {
156                throw new RuntimeException(
157                    "You must specify an external for your projects");
158            }
159        }
160    
161        public static void editWith(Attachment attachment, String editor) 
162            throws IOException 
163        {
164            new ExternalEditorThread(editor,attachment).start();            
165        }
166    
167        static class ExternalEditorThread extends Thread {
168            public ExternalEditorThread(String editor, Attachment attachment) {
169                this.editor = editor;
170                this.attachment = attachment;
171            }
172            
173            String editor;
174            Attachment attachment;
175    
176            public void run() 
177            {
178                try {
179                    java.io.File tmpFile = 
180                        File.createTempFile("UMLAF", 
181                                            attachment.getName());
182                    FileOutputStream out =
183                        new FileOutputStream(tmpFile);
184                    out.write(attachment.getData());
185                    out.close();
186                    logger.info(
187                        "Editing resource "+attachment.getName()+
188                        " with "+editor);
189                    Process proc = 
190                        Runtime.getRuntime().exec(
191                            new String[] {
192                                editor,
193                                tmpFile.getPath()
194                            });
195                    proc.waitFor();
196                    attachment.setData(
197                        Streams.readStream(new FileInputStream(tmpFile)));
198                    logger.info(
199                        "Resource "+attachment.getName()+" edited");
200                    tmpFile.delete();
201                } catch (Exception e) {
202                    logger.error(
203                        "Failed to edit resource "+attachment.getName(),e);
204                }
205            }
206        }
207    
208        public static Object getType(FieldItem field, Attachment attachment) {
209            String type = attachment.getMimeType();
210            ClassRepository cr = ClassRepository.get();
211            if ("text/x-java".equals(type)) {
212                return "javaCode";
213            }
214            return Attachment.getType(field,attachment);
215        }
216    
217        public static String getAttachmentIcon(Attachment attachment) {
218            String type = attachment.getMimeType();
219            ClassRepository cr = ClassRepository.get();
220            if ("text/x-java".equals(type)) {
221                return ResourceManager.getResource("icon_class");
222            } else {
223                return null;
224            }
225        }    
226    }
227