KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > iv > flash > commands > GenericCommand


1 /*
2  * $Id: GenericCommand.java,v 1.12 2002/07/17 05:13:37 skavish Exp $
3  *
4  * ===========================================================================
5  *
6  * The JGenerator Software License, Version 1.0
7  *
8  * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if
22  * any, must include the following acknowlegement:
23  * "This product includes software developed by Dmitry Skavish
24  * (skavish@usa.net, http://www.flashgap.com/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The name "The JGenerator" must not be used to endorse or promote
29  * products derived from this software without prior written permission.
30  * For written permission, please contact skavish@usa.net.
31  *
32  * 5. Products derived from this software may not be called "The JGenerator"
33  * nor may "The JGenerator" appear in their names without prior written
34  * permission of Dmitry Skavish.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
40  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  *
49  */

50
51 package org.openlaszlo.iv.flash.commands;
52
53 import java.io.*;
54 import java.awt.geom.*;
55 import java.lang.reflect.*;
56
57 import org.openlaszlo.iv.flash.parser.*;
58 import org.openlaszlo.iv.flash.api.*;
59 import org.openlaszlo.iv.flash.api.action.*;
60 import org.openlaszlo.iv.flash.api.shape.*;
61 import org.openlaszlo.iv.flash.api.text.*;
62 import org.openlaszlo.iv.flash.util.*;
63
64 import org.openlaszlo.iv.flash.cache.*;
65 import org.openlaszlo.iv.flash.context.Context;
66 import org.openlaszlo.iv.flash.context.ContextFactory;
67
68 /**
69  * Generic Generator command. All commands have to subclass it.
70  */

71
72 public class GenericCommand extends FlashObject {
73
74     public static final int TYPE_MOVIE = 0x01;
75     public static final int TYPE_BUTTON = 0x02;
76     public static final int TYPE_GRAPHICS = 0x04;
77     public static final int TYPE_GLOBAL = 0x08;
78
79     private int type;
80     private int depth;
81     private int flags;
82     private int frameNum;
83
84     private IVVector names = new IVVector();
85     private IVVector values = new IVVector();
86     private Instance instance;
87
88     /** Needed to track if the command was created from a MX component */
89     private boolean isComponent = false;
90
91     private static final String JavaDoc MACROMEDIACLASS = "com.macromedia.generator.commands.";
92     private static final String JavaDoc MXCOMPONENT_CMDNAME = "JGeneratorCommand";
93
94     public GenericCommand() {}
95
96     public void doCommand( FlashFile file, Context context, Script parent, int frame )
97         throws IVException
98     {
99     }
100
101     /**
102      * Sets the isComponent flag
103      *
104      * @param isComponent boolean
105      */

106     public void setIsComponent(boolean isComponent) {
107         this.isComponent = isComponent;
108     }
109
110     /**
111      * Gets the isComponent flag
112      *
113      * @retun boolean
114      */

115     public boolean isComponent() {
116         return isComponent;
117     }
118
119     public boolean isGlobal() {
120         return (type&TYPE_GLOBAL) != 0;
121     }
122
123     /**
124      * Returns command name
125      *
126      * @return command name
127      */

128     public String JavaDoc getCommandName() {
129         String JavaDoc name = getClass().getName();
130         int idx = name.lastIndexOf('.');
131         return name.substring(idx+1);
132     }
133
134     /**
135      * Returns instance
136      *
137      * @return
138      */

139     public Instance getInstance() {
140         return instance;
141     }
142
143     public void setInstance( Instance instance ) {
144         this.instance = instance;
145     }
146
147     /**
148      * Returns an instance which is associated with commands modifying instances (like Replicate)
149      * <P>
150      * <OL>
151      * <LI>if this command is MX component then
152      * <OL>
153      * <LI>get parameter "instancename"
154      * <LI>if this parameter is specified then search for an instance in the file with this name
155      * <LI>if found then use it
156      * <LI>if not found search in parent script for an instance which encloses this command.
157      * by enclosing I mean that its bounds encloses the comamnd bounds
158      * </OL>
159      * <LI>if this command is not an MX component then just use this command instance as an instance
160      * </OL>
161      *
162      * @param file current flash file
163      * @param context current context
164      * @param parent parent script (where the command is placed)
165      * @param frameNum frame number where the command is instantiated
166      * @return the instance to which this command has to be applied
167      * @exception IVException
168      */

169     public Instance getCommandInstance( FlashFile file, Context context, Script parent, int frameNum ) throws IVException {
170         Instance inst = null;
171         if( isComponent() ) {
172             String JavaDoc instancename = getParameter(context, "instancename");
173             if( instancename != null ) {
174                 instancename = instancename.trim();
175                 if( instancename.length() != 0 ) {
176                     Script main = file.getMainScript();
177                     inst = main.findInstance(instancename);
178                 }
179             }
180             if( inst == null ) {
181                 // find enclosure
182

183                 IVVector defs = new IVVector();
184                 IVVector instances = new IVVector();
185
186                 Timeline timeline = parent.getTimeline();
187                 int maxFrameNum = Math.min(timeline.getFrameCount(), frameNum+1);
188                 for( int i=0; i<maxFrameNum; i++ ) {
189                     Frame frame = timeline.getFrameAt(i);
190                     for( int k=0; k<frame.size(); k++ ) {
191                         FlashObject fo = frame.getFlashObjectAt(k);
192                         if( fo instanceof Instance ) {
193                             Instance myInst = (Instance) fo;
194                             int layer = myInst.depth;
195                             FlashDef def = myInst.def;
196                             if( def != null ) {
197                                 defs.setElementAt(def, layer);
198                             }
199                             instances.setElementAt(myInst, layer);
200                         } else if( fo instanceof RemoveObject ) {
201                             RemoveObject ro = (RemoveObject) fo;
202                             int layer = ro.depth;
203                             defs.setElementAt(null, layer);
204                             instances.setElementAt(null, layer);
205                         }
206                     }
207                 }
208
209                 Point2D ptCmd = new Point2D.Double(-1024, -1024);
210                 instance.matrix.transform(ptCmd, ptCmd);
211
212                 int myDepth = instance.depth; // depth of this command instance
213
for( int i=myDepth; --i>=0; ) {
214                     Instance myInst = (Instance) instances.elementAt(i);
215                     if( myInst == null ) continue;
216                     FlashDef def = (FlashDef) defs.elementAt(i);
217                     if( def == null || !(def instanceof Script) ) continue; // ??? error
218
Rectangle2D bounds = def.getBounds();
219                     if( bounds != null && myInst.matrix != null ) {
220                         bounds = GeomHelper.calcBounds(myInst.matrix, bounds);
221                     }
222                     if( bounds == null ) continue;
223                     if( bounds.contains(ptCmd) ) {
224                         inst = myInst;
225                         break;
226                     }
227                 }
228             }
229         } else {
230             inst = instance;
231         }
232
233         if( inst == null ) {
234             throw new IVException(Resource.CMDINSTNOTFOUND, new Object JavaDoc[] {getCommandName()});
235         } else {
236             inst.setCommand(this);
237         }
238
239         return inst;
240     }
241
242     public IVVector getParameterNames() {
243         return names;
244     }
245
246     public void setParameter( String JavaDoc name, String JavaDoc value ) {
247         for( int i=0; i<names.size(); i++ ) {
248             String JavaDoc n = (String JavaDoc) names.elementAt(i);
249             if( n.equals(name) ) {
250                 values.setElementAt(value, i);
251                 return;
252             }
253         }
254         addParameter(name, value);
255     }
256
257     public void addParameter( String JavaDoc name, String JavaDoc value ) {
258         names.addElement( name );
259         values.addElement( value );
260     }
261
262     public String JavaDoc getParameter( String JavaDoc name ) {
263         for( int i=0; i<names.size(); i++ ) {
264             String JavaDoc n = (String JavaDoc) names.elementAt(i);
265             if( n.equals(name) )
266             {
267                 String JavaDoc value = (String JavaDoc) values.elementAt(i);
268                 if ( value == null || value.trim().length() == 0 )
269                     return null;
270                 else
271                     return value;
272             }
273         }
274         return null;
275     }
276
277     public String JavaDoc getParameter( String JavaDoc name, String JavaDoc defaultValue ) {
278         String JavaDoc res = getParameter( name );
279         if( res != null ) return res;
280         return defaultValue;
281     }
282
283     public boolean getBoolParameter( String JavaDoc name ) {
284         return Util.toBool( getParameter( name ), false );
285     }
286
287     public boolean getBoolParameter( String JavaDoc name, boolean def ) {
288         return Util.toBool( getParameter( name ), def );
289     }
290
291     public String JavaDoc getParameter( Context context, String JavaDoc name, String JavaDoc def ) {
292         return context.apply( getParameter( name, def ) );
293     }
294
295     public String JavaDoc getParameter( Context context, String JavaDoc name ) {
296         return context.apply( getParameter( name ) );
297     }
298
299     public boolean getBoolParameter( Context context, String JavaDoc name, boolean def ) {
300         String JavaDoc v = context.apply( getParameter( name ) );
301         return Util.toBool( v, def );
302     }
303
304     public AlphaColor getColorParameter( Context context, String JavaDoc name, AlphaColor def ) {
305         String JavaDoc v = context.apply( getParameter( name ) );
306         return Util.toColor( v, def );
307     }
308
309     public int getIntParameter( Context context, String JavaDoc name, int def ) {
310         String JavaDoc v = context.apply( getParameter( name ) );
311         return Util.toInt( v, def );
312     }
313
314     public double getDoubleParameter( Context context, String JavaDoc name, double def ) {
315         String JavaDoc v = context.apply( getParameter( name ) );
316         return Util.toDouble( v, def );
317     }
318
319     protected int findColumn( String JavaDoc columnName, String JavaDoc[][] data ) {
320         for( int i=0; i<data[0].length; i++ ) {
321             String JavaDoc name = data[0][i];
322             if( name.equalsIgnoreCase(columnName) ) return i;
323         }
324         return -1;
325     }
326
327     protected boolean isDefault( String JavaDoc s ) {
328         return Util.isDefault(s);
329     }
330
331     /**
332      * Creates rectangular shape with default fill&amp;line styles.
333      *
334      * @param r rectangle to be used for the shape
335      * @return rectangular shape
336      */

337     protected Shape getMask( Rectangle2D r ) {
338         Shape s = new Shape();
339         s.setFillStyle0( FillStyle.newSolid( AlphaColor.white ) );
340         s.setFillStyle1( 0 );
341         s.setLineStyle( new LineStyle(1, AlphaColor.white) );
342         s.drawRectangle(r);
343         s.setBounds(r);
344         return s;
345     }
346
347     /**
348      * Adds mask for specified instance to specified script
349      * <P>
350      * Shifts all layers of all instances beginning from specified one,
351      * then adds mask to specified frame and then searches when specified
352      * instance gets removed from the timeline and if found removes the mask
353      * in the same frame.
354      * <P>
355      * The mask inherits transformation of the specified instance.
356      *
357      * @param script script to insert the mask to
358      * @param frameNum frame number to put the mask in
359      * @param inst instance to be masked
360      * @param width width of the mask
361      * @param height height of the mask
362      */

363     protected void addMask( Script script, int frameNum, Instance inst, int width, int height ) {
364         addMask(script, frameNum, inst, GeomHelper.newRectangle(0, 0, width, height));
365     }
366
367     protected void addMask( Script script, int frameNum, Instance inst, Rectangle2D maskRect ) {
368         //System.out.println( "addMask: frame="+frameNum+", inst.depth="+inst.depth );
369
int maskLayer = inst.depth;
370         script.reserveLayers(maskLayer, 1);
371         int instLayer = maskLayer+1;
372         //System.out.println( " after reserve: maskLayer="+maskLayer+", new inst.depth="+inst.depth );
373
Frame frame = script.getFrameAt(frameNum);
374         Instance maskInst = frame.addInstance( getMask(maskRect), maskLayer,
375             (AffineTransform) (inst.matrix!=null?inst.matrix.clone(): null), null);
376         maskInst.clip = instLayer;
377
378         // searches when the instance gets removed and if found remove the mask at the same time
379
int cnt = script.getFrameCount();
380         main:
381         for( int i=frameNum+1; i<cnt; i++ ) {
382             Frame f = script.getFrameAt(i);
383             int fsz = f.size();
384             for( int j=0; j<fsz; j++ ) {
385                 FlashObject o = (FlashObject) f.getFlashObjectAt(j);
386                 if( o instanceof Instance ) {
387                     Instance inst1 = (Instance) o;
388                     if( inst1.depth == instLayer && inst1.isMove && inst1.def != inst.def && inst1.def != null ) {
389                         //System.out.println( " frame="+i+", found instance: inst1.depth="+inst1.depth+", inst1.def="+inst1.def );
390
f.addFlashObject(new RemoveObject(maskLayer));
391                         break main;
392                     }
393                 } else if( o instanceof RemoveObject ) {
394                     RemoveObject ro = (RemoveObject) o;
395                     if( ro.depth == instLayer ) {
396                         //System.out.println( " frame="+i+", found remove object: ro.depth="+ro.depth );
397
f.addFlashObject(new RemoveObject(maskLayer));
398                         break main;
399                     }
400                 }
401             }
402         }
403     }
404
405     protected Font getFont( FlashFile file, String JavaDoc fontName ) {
406         FlashFile defFile = file.getDefaultSymbolFile();
407         if( defFile != null ) {
408             return defFile.getFont( fontName );
409         }
410         return null;
411     }
412
413     /**
414      * Creates simple text and calculates its bounds
415      * <P>
416      * Text should not contain newlines
417      *
418      * @param txt text
419      * @param font font
420      * @param height font height
421      * @param color text color
422      * @return created text
423      */

424     protected LazyText newSimpleText( String JavaDoc txt, Font font, int height, AlphaColor color ) {
425         LazyText text = new LazyText(true);
426
427         TextStyleChangeRecord tsr = new TextStyleChangeRecord(font, height, color);
428         tsr.setX(0);
429         tsr.setY(font.ascent);
430         text.addTextStyleChangeRecord(tsr);
431
432         TextRecord tr = new TextRecord(txt.length());
433         int l = txt.length();
434         int x = 0;
435         for( int i=0; i<l; i++ ) {
436             char ch = txt.charAt(i);
437             int idx = font.getIndex(ch);
438             if( idx == -1 ) idx = 0;
439             int adv = font.getAdvanceValue(idx);
440             if( i < l-1 ) {
441                 char ch_next = txt.charAt(i+1);
442                 int kern = font.getKerning(ch, ch_next);
443                 adv += kern;
444             }
445             tr.add(ch, idx, adv);
446             x += adv;
447         }
448
449         text.setBounds(GeomHelper.newRectangle(0, 0, x, font.ascent+font.descent));
450
451         return text;
452     }
453
454     protected Text newText( FlashFile file, String JavaDoc msg, Font font, int size, AlphaColor color, Rectangle2D rect ) {
455         Text text = Text.newText();
456         TextItem item = new TextItem( msg, font, size, color );
457         text.addTextItem( item );
458         text.setBounds( rect );
459         return text;
460     }
461
462     protected Text newText( FlashFile file, String JavaDoc msg, Font font, int size, AlphaColor color, int width, int height ) {
463         return newText( file, msg, font, size, color, GeomHelper.newRectangle(0,0,width,height) );
464     }
465
466     protected Text newText( FlashFile file, String JavaDoc msg, String JavaDoc fontName, int size, AlphaColor color, Rectangle2D rect ) {
467         Font font = getFont( file, fontName );
468         if( font == null ) return null;
469         return newText( file, msg, font, size, color, rect );
470     }
471
472     protected void processFlashDef( Instance inst, FlashFile file, Context context ) throws IVException {
473         if( inst.def != null ) {
474             inst.def.process(file, context);
475         }
476     }
477
478     protected Context makeContext( Context context, String JavaDoc[][] data, int row )
479         throws IVException
480     {
481         return ContextFactory.createContext( context, data, row );
482     }
483
484     public void setDepth( int depth ) {
485         this.depth = depth;
486     }
487
488     public void setFlags( int flags ) {
489         this.flags = flags;
490     }
491
492     public void setFrameNum( int frameNum ) {
493         this.frameNum = frameNum;
494     }
495
496     public int getDepth() {
497         return depth;
498     }
499
500     public int getFlags() {
501         return flags;
502     }
503
504     public int getFrameNum() {
505         return frameNum;
506     }
507
508     /**
509      * Sets command type
510      * <P>
511      * One of the following:
512      * <UL>
513      * <LI>TYPE_MOVIE
514      * <LI>TYPE_BUTTON
515      * <LI>TYPE_GRAPHICS
516      * <LI>TYPE_GLOBAL
517      * </UL>
518      *
519      * @param type command type
520      */

521     public void setType( int type ) {
522         this.type = type;
523     }
524
525     /**
526      * Returns command type
527      * <P>
528      * One of the following:
529      * <UL>
530      * <LI>TYPE_MOVIE
531      * <LI>TYPE_BUTTON
532      * <LI>TYPE_GRAPHICS
533      * <LI>TYPE_GLOBAL
534      * </UL>
535      *
536      * @return command type
537      */

538     public int getType() {
539         return type;
540     }
541
542     public void printContent( PrintStream out, String JavaDoc indent ) {
543         out.println( indent+"Generator Command: "+getClass().getName() );
544         out.println( indent+" Parameters: " );
545         for( int i=0; i<values.size(); i++ ) {
546             String JavaDoc name = (String JavaDoc) names.elementAt(i);
547             String JavaDoc value = (String JavaDoc) values.elementAt(i);
548             out.println( indent+" "+name+"='"+value+"'" );
549         }
550     }
551
552     public void write( FlashOutput fob ) {
553         int tagpos = fob.getPos();
554         fob.skip(6); // skip tag
555

556         fob.writeByte(type);
557         fob.writeByte(0);
558         fob.writeWord(depth);
559
560         if( (type&TYPE_GRAPHICS) != 0 ) {
561             fob.writeWord(flags);
562             fob.writeWord(frameNum);
563         }
564
565         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(100);
566         sb.append(getClass().getName());
567
568         // add parameters
569
for( int i=0; i<names.size(); i++ ) {
570             String JavaDoc n = (String JavaDoc) names.elementAt(i);
571             String JavaDoc v = (String JavaDoc) values.elementAt(i);
572             sb.append(' ');
573             sb.append(n);
574             sb.append("=\"");
575             if( v != null ) {
576                 for( int j=0; j<v.length(); j++ ) {
577                     char ch = v.charAt(j);
578                     switch(ch) {
579                         case '\n':
580                             sb.append("/n/r");
581                             break;
582                         case '"':
583                             sb.append("\\\"");
584                             break;
585                         default:
586                             sb.append(ch);
587                             break;
588                     }
589                 }
590             }
591             sb.append('"');
592         }
593
594         fob.writeStringZ(sb.toString());
595
596         fob.writeLongTagAt(getTag(), fob.getPos()-tagpos-6, tagpos);
597     }
598
599     public static GenericCommand parse( Parser p ) {
600         // 0x01 - movie
601
// 0x02 - button
602
// 0x04 - graphics
603
// 0x08 - global
604
int type = p.getUByte();
605
606         p.getUByte(); // skip 1 byte
607

608         int depth = p.getUWord();
609         int flags = 0;
610         int frameNum = 0;
611         if( (type&TYPE_GRAPHICS) != 0 ) { // graphics
612
// 0x0010 - loop
613
// 0x0020 - play once
614
// 0x0040 - single frame
615
flags = p.getUWord();
616             frameNum = p.getUWord();
617         }
618
619         String JavaDoc command = p.getString();
620         int clen = command.length();
621         int idx = command.indexOf(' ');
622         String JavaDoc className;
623         if( idx == -1 ) {
624             className = command;
625             idx = clen;
626         } else {
627             className = command.substring(0,idx);
628         }
629
630         if( className.startsWith(MACROMEDIACLASS) ) {
631             className = "org.openlaszlo.iv.flash.commands."+
632                         className.substring(MACROMEDIACLASS.length());
633         }
634         Class JavaDoc cmdClazz = CommandCache.getCommandClass(className);
635         if( cmdClazz == null ) {
636             Log.logRB( Resource.CMDNOTFOUND, new Object JavaDoc[] {className} );
637             return null;
638         }
639         GenericCommand cmd = null;
640         try {
641             cmd = (GenericCommand) cmdClazz.newInstance();
642         } catch( Exception JavaDoc e ) {
643             Log.logRB(Resource.CMDNOTCREATED, new Object JavaDoc[] {className}, e);
644             return null;
645         }
646
647         cmd.setType(type);
648         cmd.setDepth(depth);
649         cmd.setFlags(flags);
650         cmd.setFrameNum(frameNum);
651
652         /* parse parameters, idx = index of blank
653          *
654          * format:
655          * commandname name1="value1" name2="value/n/rvalue/n/rvalue\"value\"" name3="value3"
656          */

657         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
658         for( ; idx+1<clen; ) {
659             int startName = idx+1;
660             int endName = command.indexOf('=', startName);
661             String JavaDoc name = command.substring(startName, endName);
662             idx = endName+1;
663             sb.setLength(0);
664             boolean quotes = false;
665         ValueLoop:
666             while( idx < clen ) {
667                 char ch = command.charAt(idx);
668                 switch( ch ) {
669                     case '\\':
670                         sb.append( command.charAt(idx+1) );
671                         idx += 2;
672                         break;
673                     case '/':
674                         if( clen-idx >= 4 && command.charAt(idx+2)=='/' &&
675                             ( (command.charAt(idx+1)=='n' && command.charAt(idx+3)=='r' ) ||
676                               (command.charAt(idx+1)=='r' && command.charAt(idx+3)=='n' )
677                             )
678                           ) {
679                             sb.append('\n');
680                             idx += 4;
681                         } else {
682                             sb.append(ch);
683                             idx++;
684                         }
685                         break;
686                     case '"':
687                         quotes = !quotes;
688                         idx++;
689                         break;
690                     case ' ':
691                         if( !quotes ) break ValueLoop;
692                     default:
693                         sb.append(ch);
694                         idx++;
695                         break;
696                 }
697             }
698             String JavaDoc value = new String JavaDoc(sb);
699             cmd.addParameter( name, value );
700         }
701
702         return cmd;
703     }
704
705     /**
706      * Check the ClipActions to retrieve variable of Commands<br>
707      * if JGeneratorCommand variable exists in the clipEvent action
708      *
709      * @param actions ClipActions the ClipActions of the instance to test
710      * @return java.util.Hashtable the variables
711      */

712     public static GenericCommand checkAndParseMX( Instance instance ) {
713         if( instance.actions == null ) return null;
714
715         IVVector acts = instance.actions.getActions();
716
717         GenericCommand cmd = null;
718
719         // collect variables
720
for( int i = 0; i < acts.size(); i++ ) {
721             ClipAction action = (ClipAction) acts.elementAt(i);
722
723             if( action.getFlags() == ClipAction.MXCOMPONENT ) {
724
725                 Program prog = action.getProgram();
726
727                 FlashBuffer body = prog.body();
728                 body.setPos(0);
729                 boolean firstAction = true;
730                 String JavaDoc[] strings = null;
731
732                 String JavaDoc name = null;
733                 String JavaDoc value = null;
734
735                 // loop to retrieve all the variables
736
mainLoop:
737                 for (;;) {
738                     int offset = body.getPos();
739                     int code = body.getUByte();
740                     boolean hasLength = (code&0x80) != 0;
741                     int length = hasLength? body.getUWord(): 0;
742                     int nextPos = body.getPos()+length;
743
744                     switch( code ) {
745                         case Actions.None:
746                             body.setPos(nextPos);
747                             break mainLoop;
748                         case Actions.PushData: {
749                             for( int l=length; l>0; ) {
750                                 int type = body.getUByte();
751                                 l--;
752                                 switch( type ) {
753                                     case 0:
754                                         String JavaDoc ss = body.getString();
755                                         if (name == null)
756                                             name = ss;
757                                         else
758                                             value = ss;
759                                         l-=ss.length()+1;
760                                         break;
761                                     case 1:
762                                         value = new Float JavaDoc(Float.intBitsToFloat(body.getUDWord())).toString();
763                                         l-=4;
764                                         break;
765                                     case 2:
766                                     case 3:
767                                         break;
768                                     case 4:
769                                         l--;
770                                         break;
771                                     case 5:
772                                         value = new Boolean JavaDoc( body.getUByte()!=0 ).toString();
773                                         l--;
774                                         break;
775                                     case 6:
776                                         long dbits = ( ((long)body.getUDWord())<<32 ) | (((long)body.getUDWord())&0xffffffffL);
777                                         value = new Double JavaDoc(Double.longBitsToDouble(dbits)).toString();
778                                         l-=8;
779                                         break;
780                                     case 7:
781                                         value = new Integer JavaDoc(body.getUDWord()).toString();
782                                         l-=4;
783                                         break;
784                                     case 8:
785                                         int index = body.getUByte();
786                                         if ( strings != null && index < strings.length ) {
787                                             if (name == null)
788                                                 name = strings[index];
789                                             else
790                                                 value = strings[index];
791                                         }
792                                         l--;
793                                         break;
794                                 }
795                             }
796                             // if this is first action it has to be: push "JGeneratorCommand", otherwise
797
// this is not our component
798
if( firstAction && !MXCOMPONENT_CMDNAME.equals(name) )
799                                 break mainLoop;
800                             break;
801                         }
802                         case Actions.ConstantPool: {
803                             int num = body.getUWord();
804                             strings = new String JavaDoc[num];
805                             for( int j=0; j<num; j++ ) {
806                                 strings[j] = body.getString();
807                             }
808                             // if this is first action it has to have "JGeneratorCommand" in first element,
809
// otherwise this is not our component
810
if( firstAction && !MXCOMPONENT_CMDNAME.equals(strings[0]) )
811                                 break mainLoop;
812                             break;
813                         }
814                         case Actions.SetVariable:
815                             if( MXCOMPONENT_CMDNAME.equals(name) ) {
816                                 // create jgenerator command from its name
817
String JavaDoc className = "org.openlaszlo.iv.flash.commands." + value + "Command";
818
819                                 Class JavaDoc cmdClazz = CommandCache.getCommandClass(className);
820                                 if( cmdClazz == null ) {
821                                     Log.logRB( Resource.CMDNOTFOUND, new Object JavaDoc[] {className} );
822                                     return null;
823                                 }
824
825                                 // instanciate it
826
try {
827                                     cmd = (GenericCommand) cmdClazz.newInstance();
828                                 } catch( Exception JavaDoc e ) {
829                                     Log.logRB(Resource.CMDNOTCREATED, new Object JavaDoc[] {className}, e);
830                                     return null;
831                                 }
832
833                                 cmd.setDepth(instance.depth);
834                                 cmd.setType(cmd.isGlobal()?TYPE_GLOBAL:TYPE_MOVIE);
835                                 // indicate we created it from a MX component
836
cmd.setIsComponent(true);
837
838                                 // Embed it inside a MovieClip
839
Script script = new Script(1);
840                                 instance.def = script;
841                                 // we must translate the instance matrix because it is 2048x2048 centered
842
instance.matrix.translate(1024,1024);
843
844                                 // set the command
845
instance.setCommand(cmd);
846                                 cmd.setInstance(instance);
847
848                             } else {
849                                 if( cmd != null )
850                                     cmd.setParameter(name, value);
851                                 else
852                                     break mainLoop;
853                             }
854                             name = null;
855                             break;
856                         default:
857                             // all other actions mean this is not our component
858
break mainLoop;
859                     }
860                     firstAction = false;
861                 }
862             }
863
864             if( cmd != null ) {
865                 // this actions represented jgenerator mx component, remove it from list of clipactions
866
acts.removeElementAt(i);
867                 instance.actions.setMask( instance.actions.getMask()&~ClipAction.MXCOMPONENT );
868                 break; // no need for further processing
869
}
870         }
871
872         if( acts.size() == 0 ) instance.actions = null;
873
874         return cmd;
875     }
876
877     public int getTag() {
878         return Tag.TEMPLATECOMMAND;
879     }
880
881     protected FlashItem copyInto( FlashItem item, ScriptCopier copier ) {
882         super.copyInto( item, copier );
883         ((GenericCommand)item).type = type;
884         ((GenericCommand)item).depth = depth;
885         ((GenericCommand)item).flags = flags;
886         ((GenericCommand)item).frameNum = frameNum;
887         ((GenericCommand)item).instance = instance;
888         ((GenericCommand)item).isComponent = isComponent;
889         ((GenericCommand)item).names = new IVVector(names);
890         ((GenericCommand)item).values = new IVVector(values);
891         return item;
892     }
893
894     public FlashItem getCopy( ScriptCopier copier ) {
895         try {
896             Constructor c = getClass().getConstructor( new Class JavaDoc [] {} );
897             GenericCommand o = (GenericCommand) c.newInstance( new Object JavaDoc[] {} );
898             return copyInto( o, copier );
899         } catch( Exception JavaDoc e ) {
900             Log.log(e);
901             return null;
902         }
903
904     }
905
906 }
907
Popular Tags