mannersnativetest.java

来自「drools 一个开放源码的规则引擎」· Java 代码 · 共 960 行 · 第 1/3 页

JAVA
960
字号
                {
                    workingMemory.modifyObject( tuple.getFactHandleForObject( context ),
                                                context );
                }
                catch ( FactException e )
                {
                    throw new ConsequenceException( e );
                }
            }
        };
        weAreDoneRule.setConsequence( consequenceD );
        ruleSet.addRule( weAreDoneRule );

        // ==================
        // Build the RuleSet.
        // ==================
        RuleBaseBuilder builder = new RuleBaseBuilder( );
        builder.addRuleSet( ruleSet );
        RuleBase ruleBase = builder.build( );
        workingMemory = getWorkingMemory( ruleBase );
        workingMemory.addEventListener( new TestWorkingMemoryEventListener( ) );
    }

    protected void tearDown() throws Exception
    {
        workingMemory = null;
    }

    public void testManners() throws Exception
    {
        List inList = getInputObjects( generateData( ) );

        // test serialization
        workingMemory = serializeWorkingMemory( workingMemory );
        workingMemory = serializeWorkingMemory( workingMemory );

        for ( Iterator i = inList.iterator( ); i.hasNext( ); )
        {
            workingMemory.assertObject( i.next( ) );
        }

        // test serialization
        workingMemory = serializeWorkingMemory( workingMemory );
        workingMemory = serializeWorkingMemory( workingMemory );

        workingMemory.fireAllRules( );

        // test serialization
        workingMemory = serializeWorkingMemory( workingMemory );
        workingMemory = serializeWorkingMemory( workingMemory );

        List outList = workingMemory.getObjects( );

        int actualGuests = validateResults( inList,
                                            outList );

        assertEquals( numGuests,
                      actualGuests );

        TestWorkingMemoryEventListener listener = (TestWorkingMemoryEventListener) workingMemory.getEventListeners( ).get( 0 );
        assertEquals( 50,
                      listener.asserted );
        assertEquals( 0,
                      listener.retracted );
        assertEquals( 17,
                      listener.modified );
        // can't test this as it changes on each run
        // assertEquals(2024, listener.tested);
        assertEquals( 96,
                      listener.created );
        assertEquals( 17,
                      listener.fired );
        assertEquals( 79,
                      listener.cancelled );
    }

    /**
     * Verify that each guest has at least one common hobby with the guest
     * before him/her.
     */
    private static int validateResults(List inList,
                                       List outList)
    {
        int seatCount = 0;
        Guest lastGuest = null;
        Iterator it = outList.iterator( );
        while ( it.hasNext( ) )
        {
            Object obj = it.next( );
            if ( !(obj instanceof Seat) )
            {
                continue;
            }

            Seat seat = (Seat) obj;
            if ( lastGuest == null )
            {
                lastGuest = guest4Seat( inList,
                                        seat );
            }

            Guest guest = guest4Seat( inList,
                                      seat );

            boolean hobbyFound = false;
            for ( int i = 0; !hobbyFound && i < lastGuest.getHobbies( ).size( ); i++ )
            {
                String hobby = (String) lastGuest.getHobbies( ).get( i );
                if ( guest.getHobbies( ).contains( hobby ) )
                {
                    hobbyFound = true;
                }
            }

            if ( !hobbyFound )
            {
                throw new RuntimeException( "seat: " + seat.getSeat( ) + " no common hobby " + lastGuest + " -> " + guest );
            }
            seatCount++;
        }

        return seatCount;
    }

    /**
     * Gets the Guest object from the inList based on the guest name of the
     * seat.
     */
    private static Guest guest4Seat(List inList,
                                    Seat seat)
    {
        Iterator it = inList.iterator( );
        while ( it.hasNext( ) )
        {
            Object obj = it.next( );
            if ( !(obj instanceof Guest) )
            {
                continue;
            }
            Guest guest = (Guest) obj;
            if ( guest.getName( ).equals( seat.getName( ) ) )
            {
                return guest;
            }
        }

        return null;
    }

    /**
     * Convert the facts from the <code>InputStream</code> to a list of
     * objects.
     */
    private List getInputObjects(InputStream inputStream) throws IOException
    {
        List list = new ArrayList( );

        BufferedReader br = new BufferedReader( new InputStreamReader( inputStream ) );

        Map guests = new HashMap( );

        String line;
        while ( (line = br.readLine( )) != null )
        {
            if ( line.trim( ).length( ) == 0 || line.trim( ).startsWith( ";" ) )
            {
                continue;
            }
            StringTokenizer st = new StringTokenizer( line,
                                                      "() " );
            String type = st.nextToken( );

            if ( "guest".equals( type ) )
            {
                if ( !"name".equals( st.nextToken( ) ) )
                {
                    throw new IOException( "expected 'name' in: " + line );
                }
                String name = st.nextToken( );
                if ( !"sex".equals( st.nextToken( ) ) )
                {
                    throw new IOException( "expected 'sex' in: " + line );
                }
                String sex = st.nextToken( );
                if ( !"hobby".equals( st.nextToken( ) ) )
                {
                    throw new IOException( "expected 'hobby' in: " + line );
                }
                String hobby = st.nextToken( );

                Guest guest = (Guest) guests.get( name );
                if ( guest == null )
                {
                    guest = new Guest( name,
                                       sex.charAt( 0 ) );
                    guests.put( name,
                                guest );
                    list.add( guest );
                }
                guest.addHobby( hobby );
            }

            if ( "last_seat".equals( type ) )
            {
                if ( !"seat".equals( st.nextToken( ) ) )
                {
                    throw new IOException( "expected 'seat' in: " + line );
                }
                list.add( new LastSeat( new Integer( st.nextToken( ) ).intValue( ) ) );
            }

            if ( "context".equals( type ) )
            {
                if ( !"state".equals( st.nextToken( ) ) )
                {
                    throw new IOException( "expected 'state' in: " + line );
                }
                list.add( new Context( st.nextToken( ) ) );
            }
        }
        inputStream.close( );

        return list;
    }

    private InputStream generateData()
    {
        final String LINE_SEPARATOR = System.getProperty( "line.separator" );

        StringWriter writer = new StringWriter( );

        int maxMale = numGuests / 2;
        int maxFemale = numGuests / 2;

        int maleCount = 0;
        int femaleCount = 0;

        // init hobbies
        List hobbyList = new ArrayList( );
        for ( int i = 1; i <= maxHobbies; i++ )
        {
            hobbyList.add( "h" + i );
        }

        Random rnd = new Random( );
        for ( int i = 1; i <= numGuests; i++ )
        {
            char sex = rnd.nextBoolean( ) ? 'm' : 'f';
            if ( sex == 'm' && maleCount == maxMale )
            {
                sex = 'f';
            }
            if ( sex == 'f' && femaleCount == maxFemale )
            {
                sex = 'm';
            }
            if ( sex == 'm' )
            {
                maleCount++;
            }
            if ( sex == 'f' )
            {
                femaleCount++;
            }

            List guestHobbies = new ArrayList( hobbyList );

            int numHobbies = minHobbies + rnd.nextInt( maxHobbies - minHobbies + 1 );
            for ( int j = 0; j < numHobbies; j++ )
            {
                int hobbyIndex = rnd.nextInt( guestHobbies.size( ) );
                String hobby = (String) guestHobbies.get( hobbyIndex );
                writer.write( "(guest (name n" + i + ") (sex " + sex + ") (hobby " + hobby + "))" + LINE_SEPARATOR );
                guestHobbies.remove( hobbyIndex );
            }
        }
        writer.write( "(last_seat (seat " + numSeats + "))" + LINE_SEPARATOR );

        writer.write( LINE_SEPARATOR );
        writer.write( "(context (state start))" + LINE_SEPARATOR );

        return new ByteArrayInputStream( writer.getBuffer( ).toString( ).getBytes( ) );
    }

    private static WorkingMemory getWorkingMemory(RuleBase ruleBase) throws Exception
    {
        // Serialize to a byte array
        ByteArrayOutputStream bos = new ByteArrayOutputStream( );
        ObjectOutput out = new ObjectOutputStream( bos );
        out.writeObject( ruleBase.newWorkingMemory( ) );
        out.close( );

        // Get the bytes of the serialized object
        byte[] bytes = bos.toByteArray( );

        // Deserialize from a byte array
        ObjectInput in = new ObjectInputStream( new ByteArrayInputStream( bytes ) );
        WorkingMemory workingMemoryOut = (WorkingMemory) in.readObject( );
        in.close( );
        return workingMemoryOut;
    }

    private static WorkingMemory serializeWorkingMemory(WorkingMemory workingMemoryIn) throws Exception
    {
        // Serialize to a byte array
        ByteArrayOutputStream bos = new ByteArrayOutputStream( );
        ObjectOutput out = new ObjectOutputStream( bos );
        out.writeObject( workingMemoryIn );
        out.close( );

        // Get the bytes of the serialized object
        byte[] bytes = bos.toByteArray( );

        // Deserialize from a byte array
        ObjectInput in = new ObjectInputStream( new ByteArrayInputStream( bytes ) );
        WorkingMemory workingMemoryOut = (WorkingMemory) in.readObject( );
        in.close( );
        return workingMemoryOut;
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?