+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.maven.archiva</groupId>
- <artifactId>archiva</artifactId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>archiva-applet</artifactId>
- <name>Archiva Applet</name>
- <description>
- Applet for performing local operations on files such as creating a checksum of an artifact
- before uploading it.
- </description>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.1</version>
- <configuration>
- <keystore>src/keystore/keystore</keystore>
- <alias>mykey</alias>
- <storepass>password</storepass>
- <keypass>password</keypass>
- </configuration>
- <executions>
- <execution>
- <goals>
- <goal>sign</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <configuration>
- <instrumentation>
- <!-- TODO: should this module have tests? -->
- <excludes>
- <exclude>**/**</exclude>
- </excludes>
- </instrumentation>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-package org.apache.maven.archiva.applet;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import javax.swing.*;
-import java.applet.Applet;
-import java.awt.*;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivilegedAction;
-
-/**
- * Applet that takes a file on the local filesystem and checksums it for sending to the server.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- */
-public class ChecksumApplet
- extends Applet
-{
- private static final int CHECKSUM_BUFFER_SIZE = 8192;
-
- private static final int BYTE_MASK = 0xFF;
-
- private JProgressBar progressBar;
-
- public void init()
- {
- setLayout( new BorderLayout() );
- progressBar = new JProgressBar();
- progressBar.setStringPainted( true );
- add( progressBar, BorderLayout.CENTER );
- JLabel label = new JLabel( "Checksum progress: " );
- add( label, BorderLayout.WEST );
- }
-
- public String generateMd5( final String file )
- throws IOException, NoSuchAlgorithmException
- {
- Object o = AccessController.doPrivileged( new PrivilegedAction()
- {
- public Object run()
- {
- try
- {
- return checksumFile( file );
- }
- catch ( NoSuchAlgorithmException e )
- {
- return "Error checksumming file: " + e.getMessage();
- }
- catch ( FileNotFoundException e )
- {
- return "Couldn't find the file. " + e.getMessage();
- }
- catch ( IOException e )
- {
- return "Error reading file: " + e.getMessage();
- }
- }
- } );
- return (String) o;
- }
-
- protected String checksumFile( String file )
- throws NoSuchAlgorithmException, IOException
- {
- MessageDigest digest = MessageDigest.getInstance( "MD5" );
-
- long total = new File( file ).length();
- InputStream fis = new FileInputStream( file );
- try
- {
- long totalRead = 0;
- byte[] buffer = new byte[CHECKSUM_BUFFER_SIZE];
- int numRead;
- do
- {
- numRead = fis.read( buffer );
- if ( numRead > 0 )
- {
- digest.update( buffer, 0, numRead );
- totalRead += numRead;
- progressBar.setValue( (int) ( totalRead * progressBar.getMaximum() / total ) );
- }
- }
- while ( numRead != -1 );
- }
- finally
- {
- fis.close();
- }
-
- return byteArrayToHexStr( digest.digest() );
- }
-
- protected static String byteArrayToHexStr( byte[] data )
- {
- String output = "";
-
- for ( int cnt = 0; cnt < data.length; cnt++ )
- {
- //Deposit a byte into the 8 lsb of an int.
- int tempInt = data[cnt] & BYTE_MASK;
-
- //Get hex representation of the int as a string.
- String tempStr = Integer.toHexString( tempInt );
-
- //Append a leading 0 if necessary so that each hex string will contain 2 characters.
- if ( tempStr.length() == 1 )
- {
- tempStr = "0" + tempStr;
- }
-
- //Concatenate the two characters to the output string.
- output = output + tempStr;
- }
-
- return output.toUpperCase();
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <artifactId>archiva</artifactId>
- <groupId>org.apache.maven.archiva</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>archiva-security</artifactId>
- <name>Archiva Security Configuration</name>
- <dependencies>
- <dependency>
- <groupId>org.codehaus.plexus.security</groupId>
- <artifactId>plexus-security-rbac-profile</artifactId>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus.security</groupId>
- <artifactId>plexus-security-system</artifactId>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-component-api</artifactId>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>merge</id>
- <goals>
- <goal>merge-descriptors</goal>
- </goals>
- <configuration>
- <descriptors>
- <descriptor>${basedir}/src/main/resources/META-INF/plexus/components.xml</descriptor>
- <descriptor>${project.build.directory}/generated-resources/plexus/META-INF/plexus/components.xml</descriptor>
- </descriptors>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @todo why does this need to be created in the client app?
- * @todo composition instead of inheritence?
- * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile" role-hint="archiva-guest"
- */
-public class ArchivaGuestRoleProfile
- extends AbstractRoleProfile
-{
- public String getRoleName()
- {
- return ArchivaRoleConstants.GUEST_ROLE;
- }
-
- public List getOperations()
- {
- List operations = new ArrayList();
- operations.add( ArchivaRoleConstants.OPERATION_ACTIVE_GUEST );
- return operations;
- }
-
- public boolean isAssignable()
- {
- return false;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-public class ArchivaRoleConstants
-{
- public static final String DELIMITER = " - ";
-
- // globalish roles
- public static final String SYSTEM_ADMINISTRATOR_ROLE = "System Administrator";
-
- public static final String USER_ADMINISTRATOR_ROLE = "User Administrator";
-
- public static final String GLOBAL_REPOSITORY_MANAGER_ROLE = "Global Repository Manager";
-
- public static final String GLOBAL_REPOSITORY_OBSERVER_ROLE = "Global Repository Observer";
-
- public static final String REGISTERED_USER_ROLE = "Registered User";
-
- public static final String GUEST_ROLE = "Guest";
-
- // dynamic role prefixes
- public static final String REPOSITORY_MANAGER_ROLE_PREFIX = "Repository Manager";
-
- public static final String REPOSITORY_OBSERVER_ROLE_PREFIX = "Repository Observer";
-
- // operations
- public static final String OPERATION_MANAGE_USERS = "archiva-manage-users";
-
- public static final String OPERATION_MANAGE_CONFIGURATION = "archiva-manage-configuration";
-
- public static final String OPERATION_ACTIVE_GUEST = "archiva-guest";
-
- public static final String OPERATION_RUN_INDEXER = "archiva-run-indexer";
-
- public static final String OPERATION_REGENERATE_INDEX = "archiva-regenerate-index";
-
- public static final String OPERATION_ACCESS_REPORT = "archiva-access-reports";
-
- public static final String OPERATION_ADD_REPOSITORY = "archiva-add-repository";
-
- public static final String OPERATION_REPOSITORY_ACCESS = "archiva-read-repository";
-
- public static final String OPERATION_DELETE_REPOSITORY = "archiva-delete-repository";
-
- public static final String OPERATION_EDIT_REPOSITORY = "archiva-edit-repository";
-
- public static final String OPERATION_REPOSITORY_UPLOAD = "archiva-upload-repository";
-
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.DefaultRoleProfileManager;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-
-/**
- * Role profile manager.
- *
- * Role Structures are laid out as documented http://docs.codehaus.org/display/MAVENUSER/Archiva+Security+Roles
- *
- * @author Brett Porter
- * @todo composition over inheritence?
- * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfileManager" role-hint="archiva"
- */
-public class ArchivaRoleProfileManager
- extends DefaultRoleProfileManager
-{
- public void initialize()
- throws RoleProfileException
- {
- getRole( "global-repository-manager" );
- getRole( "global-repository-observer" );
-
- mergeRoleProfiles( "system-administrator", "archiva-system-administrator" );
- mergeRoleProfiles( "user-administrator", "archiva-user-administrator" );
- mergeRoleProfiles( "guest", "archiva-guest" );
- setInitialized( true ); //todo remove the initialization idea from profile managers
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @todo why does this need to be created in the client app?
- * @todo composition instead of inheritence?
- * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile" role-hint="archiva-system-administrator"
- */
-public class ArchivaSystemAdministratorRoleProfile
- extends AbstractRoleProfile
-{
- public String getRoleName()
- {
- return ArchivaRoleConstants.SYSTEM_ADMINISTRATOR_ROLE;
- }
-
- public List getOperations()
- {
- List operations = new ArrayList();
- operations.add( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION );
- operations.add( ArchivaRoleConstants.OPERATION_MANAGE_USERS );
- operations.add( ArchivaRoleConstants.OPERATION_RUN_INDEXER );
- operations.add( ArchivaRoleConstants.OPERATION_REGENERATE_INDEX );
- operations.add( ArchivaRoleConstants.OPERATION_ACCESS_REPORT ); // TODO: does this need to be templated?
- // we don't add access/upload repository operations. This isn't a sys-admin function, and we don't want to
- // encourage the use of the sys admin role for such operations. They can grant it as necessary.
- return operations;
- }
-
-
- public List getChildRoles()
- {
- List childRoles = new ArrayList();
- childRoles.add( ArchivaRoleConstants.GLOBAL_REPOSITORY_MANAGER_ROLE );
- return childRoles;
- }
-
- public boolean isAssignable()
- {
- return false;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @todo why does this need to be created in the client app?
- * @todo composition instead of inheritence?
- * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile" role-hint="archiva-user-administrator"
- */
-public class ArchivaUserAdministratorRoleProfile
- extends AbstractRoleProfile
-{
- public String getRoleName()
- {
- return ArchivaRoleConstants.USER_ADMINISTRATOR_ROLE;
- }
-
- public List getOperations()
- {
- List operations = new ArrayList();
- operations.add( ArchivaRoleConstants.OPERATION_MANAGE_USERS );
- return operations;
- }
-
- public boolean isAssignable()
- {
- return false;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile"
- * role-hint="global-repository-manager"
- */
-public class GlobalRepositoryManagerRoleProfile
- extends AbstractRoleProfile
-{
- /**
- * Create the Role name for a Repository Observer, using the provided repository id.
- *
- * @param repoId the repository id
- */
- public String getRoleName( )
- {
- return ArchivaRoleConstants.GLOBAL_REPOSITORY_MANAGER_ROLE;
- }
-
- public boolean isAssignable()
- {
- return true;
- }
-
- public List getOperations()
- {
- List operations = new ArrayList();
- operations.add( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION );
- operations.add( ArchivaRoleConstants.OPERATION_ADD_REPOSITORY );
- operations.add( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY );
- operations.add( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY );
- return operations;
- }
-
- public List getChildRoles()
- {
- List childRoles = new ArrayList();
- childRoles.add( ArchivaRoleConstants.GLOBAL_REPOSITORY_OBSERVER_ROLE );
- return childRoles;
- }
-
-
-
-
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile"
- * role-hint="global-repository-observer"
- */
-public class GlobalRepositoryObserverRoleProfile
- extends AbstractRoleProfile
-{
- /**
- * Create the Role name for a Repository Observer, using the provided repository id.
- *
- * @param repoId the repository id
- */
- public String getRoleName( )
- {
- return ArchivaRoleConstants.GLOBAL_REPOSITORY_OBSERVER_ROLE;
- }
-
- public boolean isAssignable()
- {
- return true;
- }
-
- public List getOperations()
- {
- List operations = new ArrayList();
- operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
- return operations;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.AbstractDynamicRoleProfile;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-import org.codehaus.plexus.security.rbac.RbacManagerException;
-import org.codehaus.plexus.security.rbac.RbacObjectNotFoundException;
-import org.codehaus.plexus.security.rbac.Role;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @plexus.component role="org.codehaus.plexus.rbac.profile.DynamicRoleProfile"
- * role-hint="archiva-repository-manager"
- */
-public class RepositoryManagerDynamicRoleProfile
- extends AbstractDynamicRoleProfile
-{
- /**
- * Create the Role name for a Repository Manager, using the provided repository id.
- *
- * @param repoId the repository id
- */
- public String getRoleName( String repoId )
- {
- return ArchivaRoleConstants.REPOSITORY_MANAGER_ROLE_PREFIX + ArchivaRoleConstants.DELIMITER + repoId;
- }
-
- public List getOperations()
- {
- List operations = new ArrayList();
-
- operations.add( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY );
- operations.add( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY );
- operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
- operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
- return operations;
- }
-
- public boolean isAssignable()
- {
- return true;
- }
-
-}
-
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.rbac.profile.AbstractDynamicRoleProfile;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-import org.codehaus.plexus.security.rbac.RbacManagerException;
-import org.codehaus.plexus.security.rbac.RbacObjectNotFoundException;
-import org.codehaus.plexus.security.rbac.Role;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @plexus.component role="org.codehaus.plexus.rbac.profile.DynamicRoleProfile"
- * role-hint="archiva-repository-observer"
- */
-public class RepositoryObserverDynamicRoleProfile
- extends AbstractDynamicRoleProfile
-{
- /**
- * Create the Role name for a Repository Observer, using the provided repository id.
- *
- * @param repoId the repository id
- */
- public String getRoleName( String repoId )
- {
- return ArchivaRoleConstants.REPOSITORY_OBSERVER_ROLE_PREFIX + ArchivaRoleConstants.DELIMITER + repoId;
- }
-
- public List getOperations()
- {
- List operations = new ArrayList();
- operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
- return operations;
- }
-
- public boolean isAssignable()
- {
- return true;
- }
-
-}
+++ /dev/null
-package org.apache.maven.archiva.security;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.logging.AbstractLogEnabled;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-import org.codehaus.plexus.rbac.profile.RoleProfileManager;
-import org.codehaus.plexus.security.system.check.EnvironmentCheck;
-
-import java.util.List;
-
-/**
- * @plexus.component role="org.codehaus.plexus.security.system.check.EnvironmentCheck"
- * role-hint="archiva-role-profile-check"
- * @todo isn't this standard? Shouldn't it be something initializable so it doesn't need to be checked all the time?
- */
-public class RoleProfileEnvironmentCheck
- extends AbstractLogEnabled
- implements EnvironmentCheck
-{
- /**
- * @plexus.requirement role-hint="archiva"
- */
- private RoleProfileManager roleProfileManager;
-
- public void validateEnvironment( List list )
- {
- try
- {
- if ( !roleProfileManager.isInitialized() )
- {
- roleProfileManager.initialize();
- }
- }
- catch ( RoleProfileException rpe )
- {
- list.add( "error inititalizing the role manager: " + rpe.getMessage() );
- }
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<component-set>
- <components>
- <!-- TODO: wouldn't need to redeclare if it was composition -->
- <!-- TODO: why is the container a requirement? -->
- <component>
- <role>org.codehaus.plexus.rbac.profile.RoleProfileManager</role>
- <role-hint>archiva</role-hint>
- <implementation>org.apache.maven.archiva.security.ArchivaRoleProfileManager</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.PlexusContainer</role>
- <field-name>container</field-name>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
- <field-name>knownRoleProfiles</field-name>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.rbac.profile.DynamicRoleProfile</role>
- <field-name>knownDynamicRoleProfiles</field-name>
- </requirement>
- </requirements>
- </component>
- <component>
- <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
- <role-hint>archiva-system-administrator</role-hint>
- <implementation>org.apache.maven.archiva.security.ArchivaSystemAdministratorRoleProfile</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.security.rbac.RBACManager</role>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.PlexusContainer</role>
- <field-name>container</field-name>
- </requirement>
- </requirements>
- </component>
- <component>
- <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
- <role-hint>archiva-user-administrator</role-hint>
- <implementation>org.apache.maven.archiva.security.ArchivaUserAdministratorRoleProfile</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.security.rbac.RBACManager</role>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.PlexusContainer</role>
- <field-name>container</field-name>
- </requirement>
- </requirements>
- </component>
- <component>
- <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
- <role-hint>archiva-guest</role-hint>
- <implementation>org.apache.maven.archiva.security.ArchivaGuestRoleProfile</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.security.rbac.RBACManager</role>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.PlexusContainer</role>
- <field-name>container</field-name>
- </requirement>
- </requirements>
- </component>
- <component>
- <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
- <role-hint>global-repository-manager</role-hint>
- <implementation>org.apache.maven.archiva.security.GlobalRepositoryManagerRoleProfile</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.security.rbac.RBACManager</role>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.PlexusContainer</role>
- <field-name>container</field-name>
- </requirement>
- </requirements>
- </component>
- <component>
- <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
- <role-hint>global-repository-observer</role-hint>
- <implementation>org.apache.maven.archiva.security.GlobalRepositoryObserverRoleProfile</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.security.rbac.RBACManager</role>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.PlexusContainer</role>
- <field-name>container</field-name>
- </requirement>
- </requirements>
- </component>
- <component>
- <role>org.codehaus.plexus.rbac.profile.DynamicRoleProfile</role>
- <role-hint>archiva-repository-manager</role-hint>
- <implementation>org.apache.maven.archiva.security.RepositoryManagerDynamicRoleProfile</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.security.rbac.RBACManager</role>
- </requirement>
- </requirements>
- </component>
- <component>
- <role>org.codehaus.plexus.rbac.profile.DynamicRoleProfile</role>
- <role-hint>archiva-repository-observer</role-hint>
- <implementation>org.apache.maven.archiva.security.RepositoryObserverDynamicRoleProfile</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.security.rbac.RBACManager</role>
- </requirement>
- </requirements>
- </component>
- </components>
-</component-set>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>archiva-applet</artifactId>
+ <name>Archiva Applet</name>
+ <description>
+ Applet for performing local operations on files such as creating a checksum of an artifact
+ before uploading it.
+ </description>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <keystore>src/keystore/keystore</keystore>
+ <alias>mykey</alias>
+ <storepass>password</storepass>
+ <keypass>password</keypass>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>cobertura-maven-plugin</artifactId>
+ <configuration>
+ <instrumentation>
+ <!-- TODO: should this module have tests? -->
+ <excludes>
+ <exclude>**/**</exclude>
+ </excludes>
+ </instrumentation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package org.apache.maven.archiva.applet;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import javax.swing.*;
+import java.applet.Applet;
+import java.awt.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedAction;
+
+/**
+ * Applet that takes a file on the local filesystem and checksums it for sending to the server.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ChecksumApplet
+ extends Applet
+{
+ private static final int CHECKSUM_BUFFER_SIZE = 8192;
+
+ private static final int BYTE_MASK = 0xFF;
+
+ private JProgressBar progressBar;
+
+ public void init()
+ {
+ setLayout( new BorderLayout() );
+ progressBar = new JProgressBar();
+ progressBar.setStringPainted( true );
+ add( progressBar, BorderLayout.CENTER );
+ JLabel label = new JLabel( "Checksum progress: " );
+ add( label, BorderLayout.WEST );
+ }
+
+ public String generateMd5( final String file )
+ throws IOException, NoSuchAlgorithmException
+ {
+ Object o = AccessController.doPrivileged( new PrivilegedAction()
+ {
+ public Object run()
+ {
+ try
+ {
+ return checksumFile( file );
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ return "Error checksumming file: " + e.getMessage();
+ }
+ catch ( FileNotFoundException e )
+ {
+ return "Couldn't find the file. " + e.getMessage();
+ }
+ catch ( IOException e )
+ {
+ return "Error reading file: " + e.getMessage();
+ }
+ }
+ } );
+ return (String) o;
+ }
+
+ protected String checksumFile( String file )
+ throws NoSuchAlgorithmException, IOException
+ {
+ MessageDigest digest = MessageDigest.getInstance( "MD5" );
+
+ long total = new File( file ).length();
+ InputStream fis = new FileInputStream( file );
+ try
+ {
+ long totalRead = 0;
+ byte[] buffer = new byte[CHECKSUM_BUFFER_SIZE];
+ int numRead;
+ do
+ {
+ numRead = fis.read( buffer );
+ if ( numRead > 0 )
+ {
+ digest.update( buffer, 0, numRead );
+ totalRead += numRead;
+ progressBar.setValue( (int) ( totalRead * progressBar.getMaximum() / total ) );
+ }
+ }
+ while ( numRead != -1 );
+ }
+ finally
+ {
+ fis.close();
+ }
+
+ return byteArrayToHexStr( digest.digest() );
+ }
+
+ protected static String byteArrayToHexStr( byte[] data )
+ {
+ String output = "";
+
+ for ( int cnt = 0; cnt < data.length; cnt++ )
+ {
+ //Deposit a byte into the 8 lsb of an int.
+ int tempInt = data[cnt] & BYTE_MASK;
+
+ //Get hex representation of the int as a string.
+ String tempStr = Integer.toHexString( tempInt );
+
+ //Append a leading 0 if necessary so that each hex string will contain 2 characters.
+ if ( tempStr.length() == 1 )
+ {
+ tempStr = "0" + tempStr;
+ }
+
+ //Concatenate the two characters to the output string.
+ output = output + tempStr;
+ }
+
+ return output.toUpperCase();
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>archiva</artifactId>
+ <groupId>org.apache.maven.archiva</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>archiva-security</artifactId>
+ <name>Archiva Security Configuration</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus.security</groupId>
+ <artifactId>plexus-security-rbac-profile</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus.security</groupId>
+ <artifactId>plexus-security-system</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>merge</id>
+ <goals>
+ <goal>merge-descriptors</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>${basedir}/src/main/resources/META-INF/plexus/components.xml</descriptor>
+ <descriptor>${project.build.directory}/generated-resources/plexus/META-INF/plexus/components.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @todo why does this need to be created in the client app?
+ * @todo composition instead of inheritence?
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile" role-hint="archiva-guest"
+ */
+public class ArchivaGuestRoleProfile
+ extends AbstractRoleProfile
+{
+ public String getRoleName()
+ {
+ return ArchivaRoleConstants.GUEST_ROLE;
+ }
+
+ public List getOperations()
+ {
+ List operations = new ArrayList();
+ operations.add( ArchivaRoleConstants.OPERATION_ACTIVE_GUEST );
+ return operations;
+ }
+
+ public boolean isAssignable()
+ {
+ return false;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+public class ArchivaRoleConstants
+{
+ public static final String DELIMITER = " - ";
+
+ // globalish roles
+ public static final String SYSTEM_ADMINISTRATOR_ROLE = "System Administrator";
+
+ public static final String USER_ADMINISTRATOR_ROLE = "User Administrator";
+
+ public static final String GLOBAL_REPOSITORY_MANAGER_ROLE = "Global Repository Manager";
+
+ public static final String GLOBAL_REPOSITORY_OBSERVER_ROLE = "Global Repository Observer";
+
+ public static final String REGISTERED_USER_ROLE = "Registered User";
+
+ public static final String GUEST_ROLE = "Guest";
+
+ // dynamic role prefixes
+ public static final String REPOSITORY_MANAGER_ROLE_PREFIX = "Repository Manager";
+
+ public static final String REPOSITORY_OBSERVER_ROLE_PREFIX = "Repository Observer";
+
+ // operations
+ public static final String OPERATION_MANAGE_USERS = "archiva-manage-users";
+
+ public static final String OPERATION_MANAGE_CONFIGURATION = "archiva-manage-configuration";
+
+ public static final String OPERATION_ACTIVE_GUEST = "archiva-guest";
+
+ public static final String OPERATION_RUN_INDEXER = "archiva-run-indexer";
+
+ public static final String OPERATION_REGENERATE_INDEX = "archiva-regenerate-index";
+
+ public static final String OPERATION_ACCESS_REPORT = "archiva-access-reports";
+
+ public static final String OPERATION_ADD_REPOSITORY = "archiva-add-repository";
+
+ public static final String OPERATION_REPOSITORY_ACCESS = "archiva-read-repository";
+
+ public static final String OPERATION_DELETE_REPOSITORY = "archiva-delete-repository";
+
+ public static final String OPERATION_EDIT_REPOSITORY = "archiva-edit-repository";
+
+ public static final String OPERATION_REPOSITORY_UPLOAD = "archiva-upload-repository";
+
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.DefaultRoleProfileManager;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+
+/**
+ * Role profile manager.
+ *
+ * Role Structures are laid out as documented http://docs.codehaus.org/display/MAVENUSER/Archiva+Security+Roles
+ *
+ * @author Brett Porter
+ * @todo composition over inheritence?
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfileManager" role-hint="archiva"
+ */
+public class ArchivaRoleProfileManager
+ extends DefaultRoleProfileManager
+{
+ public void initialize()
+ throws RoleProfileException
+ {
+ getRole( "global-repository-manager" );
+ getRole( "global-repository-observer" );
+
+ mergeRoleProfiles( "system-administrator", "archiva-system-administrator" );
+ mergeRoleProfiles( "user-administrator", "archiva-user-administrator" );
+ mergeRoleProfiles( "guest", "archiva-guest" );
+ setInitialized( true ); //todo remove the initialization idea from profile managers
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @todo why does this need to be created in the client app?
+ * @todo composition instead of inheritence?
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile" role-hint="archiva-system-administrator"
+ */
+public class ArchivaSystemAdministratorRoleProfile
+ extends AbstractRoleProfile
+{
+ public String getRoleName()
+ {
+ return ArchivaRoleConstants.SYSTEM_ADMINISTRATOR_ROLE;
+ }
+
+ public List getOperations()
+ {
+ List operations = new ArrayList();
+ operations.add( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION );
+ operations.add( ArchivaRoleConstants.OPERATION_MANAGE_USERS );
+ operations.add( ArchivaRoleConstants.OPERATION_RUN_INDEXER );
+ operations.add( ArchivaRoleConstants.OPERATION_REGENERATE_INDEX );
+ operations.add( ArchivaRoleConstants.OPERATION_ACCESS_REPORT ); // TODO: does this need to be templated?
+ // we don't add access/upload repository operations. This isn't a sys-admin function, and we don't want to
+ // encourage the use of the sys admin role for such operations. They can grant it as necessary.
+ return operations;
+ }
+
+
+ public List getChildRoles()
+ {
+ List childRoles = new ArrayList();
+ childRoles.add( ArchivaRoleConstants.GLOBAL_REPOSITORY_MANAGER_ROLE );
+ return childRoles;
+ }
+
+ public boolean isAssignable()
+ {
+ return false;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @todo why does this need to be created in the client app?
+ * @todo composition instead of inheritence?
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile" role-hint="archiva-user-administrator"
+ */
+public class ArchivaUserAdministratorRoleProfile
+ extends AbstractRoleProfile
+{
+ public String getRoleName()
+ {
+ return ArchivaRoleConstants.USER_ADMINISTRATOR_ROLE;
+ }
+
+ public List getOperations()
+ {
+ List operations = new ArrayList();
+ operations.add( ArchivaRoleConstants.OPERATION_MANAGE_USERS );
+ return operations;
+ }
+
+ public boolean isAssignable()
+ {
+ return false;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile"
+ * role-hint="global-repository-manager"
+ */
+public class GlobalRepositoryManagerRoleProfile
+ extends AbstractRoleProfile
+{
+ /**
+ * Create the Role name for a Repository Observer, using the provided repository id.
+ *
+ * @param repoId the repository id
+ */
+ public String getRoleName( )
+ {
+ return ArchivaRoleConstants.GLOBAL_REPOSITORY_MANAGER_ROLE;
+ }
+
+ public boolean isAssignable()
+ {
+ return true;
+ }
+
+ public List getOperations()
+ {
+ List operations = new ArrayList();
+ operations.add( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION );
+ operations.add( ArchivaRoleConstants.OPERATION_ADD_REPOSITORY );
+ operations.add( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY );
+ operations.add( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY );
+ return operations;
+ }
+
+ public List getChildRoles()
+ {
+ List childRoles = new ArrayList();
+ childRoles.add( ArchivaRoleConstants.GLOBAL_REPOSITORY_OBSERVER_ROLE );
+ return childRoles;
+ }
+
+
+
+
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.AbstractRoleProfile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.RoleProfile"
+ * role-hint="global-repository-observer"
+ */
+public class GlobalRepositoryObserverRoleProfile
+ extends AbstractRoleProfile
+{
+ /**
+ * Create the Role name for a Repository Observer, using the provided repository id.
+ *
+ * @param repoId the repository id
+ */
+ public String getRoleName( )
+ {
+ return ArchivaRoleConstants.GLOBAL_REPOSITORY_OBSERVER_ROLE;
+ }
+
+ public boolean isAssignable()
+ {
+ return true;
+ }
+
+ public List getOperations()
+ {
+ List operations = new ArrayList();
+ operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
+ return operations;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.AbstractDynamicRoleProfile;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+import org.codehaus.plexus.security.rbac.RbacManagerException;
+import org.codehaus.plexus.security.rbac.RbacObjectNotFoundException;
+import org.codehaus.plexus.security.rbac.Role;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.DynamicRoleProfile"
+ * role-hint="archiva-repository-manager"
+ */
+public class RepositoryManagerDynamicRoleProfile
+ extends AbstractDynamicRoleProfile
+{
+ /**
+ * Create the Role name for a Repository Manager, using the provided repository id.
+ *
+ * @param repoId the repository id
+ */
+ public String getRoleName( String repoId )
+ {
+ return ArchivaRoleConstants.REPOSITORY_MANAGER_ROLE_PREFIX + ArchivaRoleConstants.DELIMITER + repoId;
+ }
+
+ public List getOperations()
+ {
+ List operations = new ArrayList();
+
+ operations.add( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY );
+ operations.add( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY );
+ operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
+ operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
+ return operations;
+ }
+
+ public boolean isAssignable()
+ {
+ return true;
+ }
+
+}
+
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.rbac.profile.AbstractDynamicRoleProfile;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+import org.codehaus.plexus.security.rbac.RbacManagerException;
+import org.codehaus.plexus.security.rbac.RbacObjectNotFoundException;
+import org.codehaus.plexus.security.rbac.Role;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @plexus.component role="org.codehaus.plexus.rbac.profile.DynamicRoleProfile"
+ * role-hint="archiva-repository-observer"
+ */
+public class RepositoryObserverDynamicRoleProfile
+ extends AbstractDynamicRoleProfile
+{
+ /**
+ * Create the Role name for a Repository Observer, using the provided repository id.
+ *
+ * @param repoId the repository id
+ */
+ public String getRoleName( String repoId )
+ {
+ return ArchivaRoleConstants.REPOSITORY_OBSERVER_ROLE_PREFIX + ArchivaRoleConstants.DELIMITER + repoId;
+ }
+
+ public List getOperations()
+ {
+ List operations = new ArrayList();
+ operations.add( ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
+ return operations;
+ }
+
+ public boolean isAssignable()
+ {
+ return true;
+ }
+
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+import org.codehaus.plexus.rbac.profile.RoleProfileManager;
+import org.codehaus.plexus.security.system.check.EnvironmentCheck;
+
+import java.util.List;
+
+/**
+ * @plexus.component role="org.codehaus.plexus.security.system.check.EnvironmentCheck"
+ * role-hint="archiva-role-profile-check"
+ * @todo isn't this standard? Shouldn't it be something initializable so it doesn't need to be checked all the time?
+ */
+public class RoleProfileEnvironmentCheck
+ extends AbstractLogEnabled
+ implements EnvironmentCheck
+{
+ /**
+ * @plexus.requirement role-hint="archiva"
+ */
+ private RoleProfileManager roleProfileManager;
+
+ public void validateEnvironment( List list )
+ {
+ try
+ {
+ if ( !roleProfileManager.isInitialized() )
+ {
+ roleProfileManager.initialize();
+ }
+ }
+ catch ( RoleProfileException rpe )
+ {
+ list.add( "error inititalizing the role manager: " + rpe.getMessage() );
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<component-set>
+ <components>
+ <!-- TODO: wouldn't need to redeclare if it was composition -->
+ <!-- TODO: why is the container a requirement? -->
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.RoleProfileManager</role>
+ <role-hint>archiva</role-hint>
+ <implementation>org.apache.maven.archiva.security.ArchivaRoleProfileManager</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.PlexusContainer</role>
+ <field-name>container</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
+ <field-name>knownRoleProfiles</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.rbac.profile.DynamicRoleProfile</role>
+ <field-name>knownDynamicRoleProfiles</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
+ <role-hint>archiva-system-administrator</role-hint>
+ <implementation>org.apache.maven.archiva.security.ArchivaSystemAdministratorRoleProfile</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.security.rbac.RBACManager</role>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.PlexusContainer</role>
+ <field-name>container</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
+ <role-hint>archiva-user-administrator</role-hint>
+ <implementation>org.apache.maven.archiva.security.ArchivaUserAdministratorRoleProfile</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.security.rbac.RBACManager</role>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.PlexusContainer</role>
+ <field-name>container</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
+ <role-hint>archiva-guest</role-hint>
+ <implementation>org.apache.maven.archiva.security.ArchivaGuestRoleProfile</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.security.rbac.RBACManager</role>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.PlexusContainer</role>
+ <field-name>container</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
+ <role-hint>global-repository-manager</role-hint>
+ <implementation>org.apache.maven.archiva.security.GlobalRepositoryManagerRoleProfile</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.security.rbac.RBACManager</role>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.PlexusContainer</role>
+ <field-name>container</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.RoleProfile</role>
+ <role-hint>global-repository-observer</role-hint>
+ <implementation>org.apache.maven.archiva.security.GlobalRepositoryObserverRoleProfile</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.security.rbac.RBACManager</role>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.PlexusContainer</role>
+ <field-name>container</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.DynamicRoleProfile</role>
+ <role-hint>archiva-repository-manager</role-hint>
+ <implementation>org.apache.maven.archiva.security.RepositoryManagerDynamicRoleProfile</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.security.rbac.RBACManager</role>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.rbac.profile.DynamicRoleProfile</role>
+ <role-hint>archiva-repository-observer</role-hint>
+ <implementation>org.apache.maven.archiva.security.RepositoryObserverDynamicRoleProfile</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.security.rbac.RBACManager</role>
+ </requirement>
+ </requirements>
+ </component>
+ </components>
+</component-set>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>archiva-webapp</artifactId>
+ <packaging>war</packaging>
+ <name>Archiva Web Application</name>
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jsp-api</artifactId>
+ <version>2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>opensymphony</groupId>
+ <artifactId>sitemesh</artifactId>
+ <version>2.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>taglibs</groupId>
+ <artifactId>standard</artifactId>
+ <version>1.1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-app-configuration-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-app-configuration-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-slf4j-logging</artifactId>
+ <version>1.1-alpha-1-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0.4</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http-lightweight</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>opensymphony</groupId>
+ <artifactId>webwork</artifactId>
+ <version>2.2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus.registry</groupId>
+ <artifactId>plexus-registry-api</artifactId>
+ <version>1.0-alpha-2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus.registry</groupId>
+ <artifactId>plexus-registry-commons</artifactId>
+ <version>1.0-alpha-2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-proxy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-security</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-applet</artifactId>
+ <!-- TODO: actually, just exclude from WAR plugin -->
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-dependency-tree</artifactId>
+ <version>1.0-alpha-2</version>
+ </dependency>
+ <!-- Plexus Security Dependencies -->
+ <dependency>
+ <groupId>org.codehaus.plexus.security</groupId>
+ <artifactId>plexus-security-ui-web</artifactId>
+ <type>war</type>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus.security</groupId>
+ <artifactId>plexus-security-ui-web-taglib</artifactId>
+ </dependency>
+ <!-- Other dependencies -->
+ <dependency>
+ <groupId>org.codehaus.plexus.webdav</groupId>
+ <artifactId>plexus-webdav-simple</artifactId>
+ <version>1.0-alpha-1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-xwork-integration</artifactId>
+ <version>1.0-alpha-6-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <version>10.1.3.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.1.1</version>
+ <!-- This configuration is added to cleanup from war:inplace -->
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>${basedir}/src/main/webapp</directory>
+ <includes>
+ <!-- TODO: META-INF shouldn't be required, seems to be an issue with the current war plugin -->
+ <include>META-INF</include>
+ <include>images/pss</include>
+ <!-- Images from other wars -->
+ <include>template/pss</include>
+ <!-- Templates from other wars -->
+ <include>WEB-INF/classes</include>
+ <!-- Classes and Resources from other wars -->
+ <include>WEB-INF/lib</include>
+ <!-- Dependencies from other wars -->
+ <include>WEB-INF/database</include>
+ <!-- Database location configured in application.xml -->
+ <include>WEB-INF/logs</include>
+ <!-- Log file location specified in application.xml -->
+ <include>pss</include>
+ <!-- plexus-security css and javascript -->
+ <include>css/pss</include>
+ <include>WEB-INF/jsp/pss</include>
+ <!-- plexus-security jsps -->
+ <include>WEB-INF/template/pss</include>
+ <!-- plexus-security xwork templates -->
+ <include>WEB-INF/logs</include>
+ <!-- Directory created by jetty:run -->
+ <include>WEB-INF/temp</include>
+ <!-- Directory created by jetty:run -->
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.0.1</version>
+ <configuration>
+ <!-- Some versions of maven-war-plugin (snapshots) have this incorrectly defaulted to true.
+ Specifically setting this to false to avoid accidental jar file creation. -->
+ <archiveClasses>false</archiveClasses>
+ <dependentWarExcludes>META-INF/**,WEB-INF/web.xml,WEB-INF/classes/xwork.xml</dependentWarExcludes>
+ </configuration>
+ <!-- TODO: would be good to make the jetty plugin aware of these and remove the below -->
+ <executions>
+ <execution>
+ <phase>compile</phase>
+ <goals>
+ <!-- Needed to get the plexus-security war overlay to do its thing before jetty:run -->
+ <goal>inplace</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>maven-jetty-plugin</artifactId>
+ <version>6.1.1</version>
+ <configuration>
+ <scanIntervalSeconds>10</scanIntervalSeconds>
+ <contextPath>/</contextPath>
+ <jettyEnvXml>src/jetty-env.xml</jettyEnvXml>
+ <connectors>
+ <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+ <port>9091</port>
+ <maxIdleTime>60000</maxIdleTime>
+ </connector>
+ </connectors>
+ <systemProperties>
+ <systemProperty>
+ <name>appserver.base</name>
+ <value>${project.build.directory}/appserver-base</value>
+ </systemProperty>
+ <systemProperty>
+ <name>derby.system.home</name>
+ <value>${project.build.directory}/appserver-base/logs</value>
+ </systemProperty>
+ </systemProperties>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <version>10.1.3.1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>dependency-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>archiva-applet</artifactId>
+ <version>${project.version}</version>
+ <outputDirectory>src/main/webapp</outputDirectory>
+ <destFileName>archiva-applet.jar</destFileName>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-maven-plugin</artifactId>
+ <configuration>
+ <roleDefaults>
+ <roleDefault>
+ <role>com.opensymphony.xwork.Action</role>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
+ </roleDefault>
+ </roleDefaults>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>cobertura-maven-plugin</artifactId>
+ <!-- TODO! add unit tests -->
+ <configuration>
+ <instrumentation>
+ <excludes>
+ <exclude>**/**</exclude>
+ </excludes>
+ </instrumentation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <copy todir="${project.build.directory}/appserver-base">
+ <fileset dir="src/appserver-base" />
+ </copy>
+ </tasks>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<configuration />
--- /dev/null
+<configuration />
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+<Configure class="org.mortbay.jetty.webapp.WebAppContext">
+
+ <New id="validation_mail" class="org.mortbay.jetty.plus.naming.Resource">
+ <Arg>mail/Session</Arg>
+ <Arg>
+ <New class="org.mortbay.naming.factories.MailSessionReference">
+ <Set name="user"></Set>
+ <Set name="password"></Set>
+ <Set name="properties">
+ <New class="java.util.Properties">
+ <Put name="mail.smtp.host">localhost</Put>
+ <Put name="mail.smtp.port">25</Put> <!-- TODO: shouldn't this default? -->
+ </New>
+ </Set>
+ </New>
+ </Arg>
+ </New>
+
+ <!-- Archiva database -->
+ <New id="archiva" class="org.mortbay.jetty.plus.naming.Resource">
+ <Arg>jdbc/archiva</Arg>
+ <Arg>
+ <New class="org.apache.derby.jdbc.EmbeddedDataSource">
+ <Set name="DatabaseName">target/databases/archiva</Set>
+ <Set name="user">sa</Set>
+ <Set name="createDatabase">create</Set>
+ </New>
+ </Arg>
+ </New>
+
+ <New id="archivaShutdown" class="org.mortbay.jetty.plus.naming.Resource">
+ <Arg>jdbc/archivaShutdown</Arg>
+ <Arg>
+ <New class="org.apache.derby.jdbc.EmbeddedDataSource">
+ <Set name="DatabaseName">target/databases/archiva</Set>
+ <Set name="user">sa</Set>
+ <Set name="shutdownDatabase">shutdown</Set>
+ </New>
+ </Arg>
+ </New>
+
+ <!-- Users / Security Database -->
+ <New id="users" class="org.mortbay.jetty.plus.naming.Resource">
+ <Arg>jdbc/users</Arg>
+ <Arg>
+ <New class="org.apache.derby.jdbc.EmbeddedDataSource">
+ <Set name="DatabaseName">target/databases/users</Set>
+ <Set name="user">sa</Set>
+ <Set name="createDatabase">create</Set>
+ </New>
+ </Arg>
+ </New>
+
+ <New id="usersShutdown" class="org.mortbay.jetty.plus.naming.Resource">
+ <Arg>jdbc/usersShutdown</Arg>
+ <Arg>
+ <New class="org.apache.derby.jdbc.EmbeddedDataSource">
+ <Set name="DatabaseName">target/databases/users</Set>
+ <Set name="user">sa</Set>
+ <Set name="shutdownDatabase">shutdown</Set>
+ </New>
+ </Arg>
+ </New>
+
+</Configure>
+
--- /dev/null
+package org.apache.maven.archiva.web.action;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+public abstract class AbstractConfiguredAction
+ extends PlexusActionSupport
+{
+ /**
+ * @plexus.requirement
+ */
+ private ConfiguredRepositoryFactory repositoryFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ protected ArtifactRepository createLocalRepository()
+ {
+ Configuration configuration = archivaConfiguration.getConfiguration();
+
+ return repositoryFactory.createLocalRepository( configuration );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
+import org.apache.maven.archiva.indexer.RepositoryIndexException;
+import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+/**
+ * Browse the repository.
+ *
+ * @todo cache should be a proper cache class that is a singleton requirement rather than static variables
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="browseAction"
+ */
+public class BrowseAction
+ extends PlexusActionSupport
+{
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryArtifactIndexFactory factory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ConfiguredRepositoryFactory repositoryFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ private List groups;
+
+ private String groupId;
+
+ private static final String GROUP_SEPARATOR = ".";
+
+ private List artifactIds;
+
+ private String artifactId;
+
+ private List versions;
+
+ private static GroupTreeNode rootNode;
+
+ private static long groupCacheTime;
+
+ public String browse()
+ throws RepositoryIndexException, IOException
+ {
+ RepositoryArtifactIndex index = getIndex();
+
+ if ( !index.exists() )
+ {
+ addActionError( "The repository is not yet indexed. Please wait, and then try again." );
+ return ERROR;
+ }
+
+ GroupTreeNode rootNode = buildGroupTree( index );
+
+ this.groups = collateGroups( rootNode );
+
+ return SUCCESS;
+ }
+
+ public String browseGroup()
+ throws RepositoryIndexException, IOException, RepositoryIndexSearchException
+ {
+ RepositoryArtifactIndex index = getIndex();
+
+ if ( !index.exists() )
+ {
+ addActionError( "The repository is not yet indexed. Please wait, and then try again." );
+ return ERROR;
+ }
+
+ GroupTreeNode rootNode = buildGroupTree( index );
+
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ // TODO: i18n
+ addActionError( "You must specify a group ID to browse" );
+ return ERROR;
+ }
+
+ StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
+ while ( tok.hasMoreTokens() )
+ {
+ String part = tok.nextToken();
+
+ if ( !rootNode.getChildren().containsKey( part ) )
+ {
+ // TODO: i18n
+ getLogger().debug(
+ "Can't find part: " + part + " for groupId " + groupId + " in children " + rootNode.getChildren() );
+ addActionError( "The group specified was not found" );
+ return ERROR;
+ }
+ else
+ {
+ rootNode = (GroupTreeNode) rootNode.getChildren().get( part );
+ }
+ }
+
+ this.groups = collateGroups( rootNode );
+
+ this.artifactIds = index.getArtifactIds( groupId );
+ Collections.sort( this.artifactIds );
+
+ return SUCCESS;
+ }
+
+ public String browseArtifact()
+ throws RepositoryIndexException, IOException, RepositoryIndexSearchException
+ {
+ RepositoryArtifactIndex index = getIndex();
+
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ // TODO: i18n
+ addActionError( "You must specify a group ID to browse" );
+ return ERROR;
+ }
+
+ if ( StringUtils.isEmpty( artifactId ) )
+ {
+ // TODO: i18n
+ addActionError( "You must specify a artifact ID to browse" );
+ return ERROR;
+ }
+
+ this.versions = index.getVersions( groupId, artifactId );
+ Collections.sort( this.versions );
+
+ if ( versions.isEmpty() )
+ {
+ // TODO: i18n
+ addActionError( "Could not find any artifacts with the given group and artifact ID" );
+ return ERROR;
+ }
+
+ return SUCCESS;
+ }
+
+ private GroupTreeNode buildGroupTree( RepositoryArtifactIndex index )
+ throws IOException, RepositoryIndexException
+ {
+ // TODO: give action message if indexing is in progress
+
+ long lastUpdate = index.getLastUpdatedTime();
+
+ if ( rootNode == null || lastUpdate > groupCacheTime )
+ {
+ List groups = index.getAllGroupIds();
+
+ getLogger().info( "Loaded " + groups.size() + " groups from index" );
+
+ rootNode = new GroupTreeNode();
+
+ // build a tree structure
+ for ( Iterator i = groups.iterator(); i.hasNext(); )
+ {
+ String groupId = (String) i.next();
+
+ StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
+
+ GroupTreeNode node = rootNode;
+
+ while ( tok.hasMoreTokens() )
+ {
+ String part = tok.nextToken();
+
+ if ( !node.getChildren().containsKey( part ) )
+ {
+ GroupTreeNode newNode = new GroupTreeNode( part, node );
+ node.addChild( newNode );
+ node = newNode;
+ }
+ else
+ {
+ node = (GroupTreeNode) node.getChildren().get( part );
+ }
+ }
+ }
+ groupCacheTime = lastUpdate;
+ }
+ else
+ {
+ getLogger().debug( "Loaded groups from cache" );
+ }
+
+ return rootNode;
+ }
+
+ private List collateGroups( GroupTreeNode rootNode )
+ {
+ List groups = new ArrayList();
+ for ( Iterator i = rootNode.getChildren().values().iterator(); i.hasNext(); )
+ {
+ GroupTreeNode node = (GroupTreeNode) i.next();
+
+ while ( node.getChildren().size() == 1 )
+ {
+ node = (GroupTreeNode) node.getChildren().values().iterator().next();
+ }
+
+ groups.add( node.getFullName() );
+ }
+ return groups;
+ }
+
+ private RepositoryArtifactIndex getIndex()
+ throws RepositoryIndexException
+ {
+ Configuration configuration = archivaConfiguration.getConfiguration();
+ File indexPath = new File( configuration.getIndexPath() );
+
+ return factory.createStandardIndex( indexPath );
+ }
+
+ public List getGroups()
+ {
+ return groups;
+ }
+
+ public List getArtifactIds()
+ {
+ return artifactIds;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ public List getVersions()
+ {
+ return versions;
+ }
+
+ private static class GroupTreeNode
+ {
+ private final String name;
+
+ private final String fullName;
+
+ private final Map children = new TreeMap();
+
+ GroupTreeNode()
+ {
+ name = null;
+ fullName = null;
+ }
+
+ GroupTreeNode( String name, GroupTreeNode parent )
+ {
+ this.name = name;
+ this.fullName = parent.fullName != null ? parent.fullName + GROUP_SEPARATOR + name : name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getFullName()
+ {
+ return fullName;
+ }
+
+ public Map getChildren()
+ {
+ return children;
+ }
+
+ public void addChild( GroupTreeNode newNode )
+ {
+ children.put( newNode.name, newNode );
+ }
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.reporting.database.ReportingDatabase;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.codehaus.plexus.security.rbac.Resource;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+import java.util.List;
+
+/**
+ * Repository reporting.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="reportsAction"
+ * @todo split report access and report generation
+ */
+public class ReportsAction
+ extends PlexusActionSupport
+ implements SecureAction
+{
+ /**
+ * @plexus.requirement
+ */
+ private ReportingDatabase database;
+
+ private List reports;
+
+ public String execute()
+ throws Exception
+ {
+ reports = database.getArtifactDatabase().getAllArtifactResults();
+
+ return SUCCESS;
+ }
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+
+ bundle.setRequiresAuthentication( true );
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL );
+
+ return bundle;
+ }
+
+ public List getReports()
+ {
+ return reports;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.queryParser.MultiFieldQueryParser;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.TermQuery;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
+import org.apache.maven.archiva.indexer.RepositoryIndexException;
+import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
+import org.apache.maven.archiva.indexer.lucene.LuceneQuery;
+import org.apache.maven.archiva.indexer.lucene.LuceneRepositoryArtifactIndex;
+import org.apache.maven.archiva.indexer.record.StandardIndexRecordFields;
+import org.apache.maven.archiva.web.util.VersionMerger;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.util.Collection;
+
+/**
+ * Search all indexed fields by the given criteria.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="searchAction"
+ */
+public class SearchAction
+ extends PlexusActionSupport
+{
+ /**
+ * Query string.
+ */
+ private String q;
+
+ /**
+ * The MD5 to search by.
+ */
+ private String md5;
+
+ /**
+ * Search results.
+ */
+ private Collection searchResults;
+
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryArtifactIndexFactory factory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ConfiguredRepositoryFactory repositoryFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ private static final String RESULTS = "results";
+
+ private static final String ARTIFACT = "artifact";
+
+ private String infoMessage;
+
+ public String quickSearch()
+ throws MalformedURLException, RepositoryIndexException, RepositoryIndexSearchException, ParseException
+ {
+ // TODO: give action message if indexing is in progress
+
+ assert q != null && q.length() != 0;
+
+ RepositoryArtifactIndex index = getIndex();
+
+ if ( !index.exists() )
+ {
+ addActionError( "The repository is not yet indexed. Please wait, and then try again." );
+ return ERROR;
+ }
+
+ MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{StandardIndexRecordFields.GROUPID,
+ StandardIndexRecordFields.ARTIFACTID, StandardIndexRecordFields.BASE_VERSION,
+ StandardIndexRecordFields.CLASSIFIER, StandardIndexRecordFields.CLASSES, StandardIndexRecordFields.FILES,
+ StandardIndexRecordFields.TYPE, StandardIndexRecordFields.PROJECT_NAME,
+ StandardIndexRecordFields.PROJECT_DESCRIPTION}, LuceneRepositoryArtifactIndex.getAnalyzer() );
+ searchResults = index.search( new LuceneQuery( parser.parse( q ) ) );
+
+ if ( searchResults.isEmpty() )
+ {
+ addActionError( "No results found" );
+ return INPUT;
+ }
+
+ searchResults = VersionMerger.merge( searchResults );
+
+ return SUCCESS;
+ }
+
+ public String findArtifact()
+ throws Exception
+ {
+ // TODO: give action message if indexing is in progress
+
+ assert md5 != null && md5.length() != 0;
+
+ RepositoryArtifactIndex index = getIndex();
+
+ if ( !index.exists() )
+ {
+ addActionError( "The repository is not yet indexed. Please wait, and then try again." );
+ return ERROR;
+ }
+
+ searchResults = index.search(
+ new LuceneQuery( new TermQuery( new Term( StandardIndexRecordFields.MD5, md5.toLowerCase() ) ) ) );
+
+ if ( searchResults.isEmpty() )
+ {
+ addActionError( "No results found" );
+ return INPUT;
+ }
+ if ( searchResults.size() == 1 )
+ {
+ return ARTIFACT;
+ }
+ else
+ {
+ return RESULTS;
+ }
+ }
+
+ private RepositoryArtifactIndex getIndex()
+ throws RepositoryIndexException
+ {
+ Configuration configuration = archivaConfiguration.getConfiguration();
+ File indexPath = new File( configuration.getIndexPath() );
+
+ return factory.createStandardIndex( indexPath );
+ }
+
+ public String doInput()
+ {
+ return INPUT;
+ }
+
+ public String getQ()
+ {
+ return q;
+ }
+
+ public void setQ( String q )
+ {
+ this.q = q;
+ }
+
+ public String getMd5()
+ {
+ return md5;
+ }
+
+ public void setMd5( String md5 )
+ {
+ this.md5 = md5;
+ }
+
+ public Collection getSearchResults()
+ {
+ return searchResults;
+ }
+
+ public String getInfoMessage()
+ {
+ return infoMessage;
+ }
+
+ public void setInfoMessage( String infoMessage )
+ {
+ this.infoMessage = infoMessage;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.TermQuery;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
+import org.apache.maven.archiva.indexer.RepositoryIndexException;
+import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
+import org.apache.maven.archiva.indexer.lucene.LuceneQuery;
+import org.apache.maven.archiva.indexer.record.StandardArtifactIndexRecord;
+import org.apache.maven.archiva.proxy.ProxyException;
+import org.apache.maven.archiva.reporting.database.ArtifactResultsDatabase;
+import org.apache.maven.archiva.web.util.VersionMerger;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactCollector;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+import org.apache.maven.shared.dependency.tree.DependencyNode;
+import org.apache.maven.shared.dependency.tree.DependencyTree;
+import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
+import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Browse the repository.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="showArtifactAction"
+ */
+public class ShowArtifactAction
+ extends PlexusActionSupport
+{
+ /**
+ * @plexus.requirement
+ */
+ private ArtifactFactory artifactFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ConfiguredRepositoryFactory repositoryFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private MavenProjectBuilder projectBuilder;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryArtifactIndexFactory factory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArtifactMetadataSource artifactMetadataSource;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArtifactCollector collector;
+
+ /**
+ * @plexus.requirement
+ */
+ private DependencyTreeBuilder dependencyTreeBuilder;
+
+ /**
+ * @plexus.requirement
+ */
+ ArtifactResultsDatabase artifactsDatabase;
+
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ private Model model;
+
+ private Collection dependencies;
+
+ private List dependencyTree;
+
+ private String repositoryId;
+
+ private String repositoryUrlName;
+
+ private String artifactPath;
+
+ private List mailingLists;
+
+ private List reports;
+
+ public String artifact()
+ throws IOException, XmlPullParserException, ProjectBuildingException, ResourceDoesNotExistException,
+ ProxyException, ArtifactResolutionException
+ {
+ if ( !checkParameters() )
+ {
+ return ERROR;
+ }
+
+ MavenProject project = readProject();
+
+ model = project.getModel();
+
+ return SUCCESS;
+ }
+
+ public String dependencies()
+ throws IOException, XmlPullParserException, ProjectBuildingException
+ {
+ if ( !checkParameters() )
+ {
+ return ERROR;
+ }
+
+ MavenProject project = readProject();
+
+ model = project.getModel();
+
+ // TODO: should this be the whole set of artifacts, and be more like the maven dependencies report?
+ this.dependencies = VersionMerger.wrap( project.getModel().getDependencies() );
+
+ return SUCCESS;
+ }
+
+ public String mailingLists()
+ throws IOException, XmlPullParserException, ProjectBuildingException
+ {
+ if ( !checkParameters() )
+ {
+ return ERROR;
+ }
+
+ MavenProject project = readProject();
+
+ model = project.getModel();
+
+ this.mailingLists = project.getMailingLists();
+
+ return SUCCESS;
+ }
+
+ public String reports()
+ throws IOException, XmlPullParserException, ProjectBuildingException
+ {
+ if ( !checkParameters() )
+ {
+ return ERROR;
+ }
+
+ System.out.println("#### In reports.");
+ this.reports = artifactsDatabase.findArtifactResults( groupId, artifactId, version );
+ System.out.println("#### Found " + reports.size() + " reports.");
+
+ return SUCCESS;
+ }
+
+ public String dependees()
+ throws IOException, XmlPullParserException, ProjectBuildingException, RepositoryIndexException,
+ RepositoryIndexSearchException
+ {
+ if ( !checkParameters() )
+ {
+ return ERROR;
+ }
+
+ MavenProject project = readProject();
+
+ model = project.getModel();
+
+ RepositoryArtifactIndex index = getIndex();
+
+ String id = createId( groupId, artifactId, version );
+ List records = index.search( new LuceneQuery( new TermQuery( new Term( "dependencies", id ) ) ) );
+
+ dependencies = VersionMerger.merge( records );
+
+ return SUCCESS;
+ }
+
+ public String dependencyTree()
+ throws ProjectBuildingException, InvalidDependencyVersionException, ArtifactResolutionException
+ {
+ if ( !checkParameters() )
+ {
+ return ERROR;
+ }
+
+ Configuration configuration = archivaConfiguration.getConfiguration();
+ List repositories = repositoryFactory.createRepositories( configuration );
+
+ Artifact artifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
+ // TODO: maybe we can decouple the assembly parts of the project builder from the repository handling to get rid of the temp repo
+ ArtifactRepository localRepository = repositoryFactory.createLocalRepository( configuration );
+ MavenProject project = projectBuilder.buildFromRepository( artifact, repositories, localRepository );
+
+ model = project.getModel();
+
+ getLogger().debug( " processing : " + groupId + ":" + artifactId + ":" + version );
+
+ DependencyTree dependencies = collectDependencies( project, localRepository );
+
+ this.dependencyTree = new ArrayList();
+
+ populateFlatTreeList( dependencies.getRootNode(), dependencyTree );
+
+ return SUCCESS;
+ }
+
+ private void populateFlatTreeList( DependencyNode currentNode, List dependencyList )
+ {
+ DependencyNode childNode;
+
+ for ( Iterator iterator = currentNode.getChildren().iterator(); iterator.hasNext(); )
+ {
+ childNode = (DependencyNode) iterator.next();
+ dependencyList.add( childNode );
+ populateFlatTreeList( childNode, dependencyList );
+ }
+ }
+
+ private DependencyTree collectDependencies( MavenProject project, ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ProjectBuildingException, InvalidDependencyVersionException
+ {
+ try
+ {
+ return dependencyTreeBuilder.buildDependencyTree( project, localRepository, artifactFactory,
+ artifactMetadataSource, collector );
+ }
+ catch ( DependencyTreeBuilderException e )
+ {
+ getLogger().error( "Unable to build dependency tree.", e );
+ return null;
+ }
+ }
+
+ private static String createId( String groupId, String artifactId, String version )
+ {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ private RepositoryArtifactIndex getIndex()
+ throws RepositoryIndexException
+ {
+ Configuration configuration = archivaConfiguration.getConfiguration();
+ File indexPath = new File( configuration.getIndexPath() );
+
+ return factory.createStandardIndex( indexPath );
+ }
+
+ private MavenProject readProject()
+ throws ProjectBuildingException
+ {
+ Configuration configuration = archivaConfiguration.getConfiguration();
+ List repositories = repositoryFactory.createRepositories( configuration );
+
+ Artifact artifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
+ // TODO: maybe we can decouple the assembly parts of the project builder from the repository handling to get rid of the temp repo
+ ArtifactRepository localRepository = repositoryFactory.createLocalRepository( configuration );
+ return projectBuilder.buildFromRepository( artifact, repositories, localRepository );
+ }
+
+ private boolean checkParameters()
+ {
+ boolean result = true;
+
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ // TODO: i18n
+ addActionError( "You must specify a group ID to browse" );
+ result = false;
+ }
+
+ else if ( StringUtils.isEmpty( artifactId ) )
+ {
+ // TODO: i18n
+ addActionError( "You must specify a artifact ID to browse" );
+ result = false;
+ }
+
+ else if ( StringUtils.isEmpty( version ) )
+ {
+ // TODO: i18n
+ addActionError( "You must specify a version to browse" );
+ result = false;
+ }
+ return result;
+ }
+
+ public Model getModel()
+ {
+ return model;
+ }
+
+ public Collection getDependencies()
+ {
+ return dependencies;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ public List getDependencyTree()
+ {
+ return dependencyTree;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public String getArtifactPath()
+ {
+ return artifactPath;
+ }
+
+ public static class DependencyWrapper
+ {
+ private final String groupId;
+
+ private final String artifactId;
+
+ /**
+ * Versions added. We ignore duplicates since you might add those with varying classifiers.
+ */
+ private Set versions = new HashSet();
+
+ private String version;
+
+ private String scope;
+
+ private String classifier;
+
+ public DependencyWrapper( StandardArtifactIndexRecord record )
+ {
+ this.groupId = record.getGroupId();
+
+ this.artifactId = record.getArtifactId();
+
+ addVersion( record.getVersion() );
+ }
+
+ public DependencyWrapper( Dependency dependency )
+ {
+ this.groupId = dependency.getGroupId();
+
+ this.artifactId = dependency.getArtifactId();
+
+ this.scope = dependency.getScope();
+
+ this.classifier = dependency.getClassifier();
+
+ addVersion( dependency.getVersion() );
+ }
+
+ public String getScope()
+ {
+ return scope;
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public void addVersion( String version )
+ {
+ // We use DefaultArtifactVersion to get the correct sorting order later, however it does not have
+ // hashCode properly implemented, so we add it here.
+ // TODO: add these methods to the actual DefaultArtifactVersion and use that.
+ versions.add( new DefaultArtifactVersion( version )
+ {
+ public int hashCode()
+ {
+ int result;
+ result = getBuildNumber();
+ result = 31 * result + getMajorVersion();
+ result = 31 * result + getMinorVersion();
+ result = 31 * result + getIncrementalVersion();
+ result = 31 * result + ( getQualifier() != null ? getQualifier().hashCode() : 0 );
+ return result;
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+
+ DefaultArtifactVersion that = (DefaultArtifactVersion) o;
+
+ if ( getBuildNumber() != that.getBuildNumber() )
+ {
+ return false;
+ }
+ if ( getIncrementalVersion() != that.getIncrementalVersion() )
+ {
+ return false;
+ }
+ if ( getMajorVersion() != that.getMajorVersion() )
+ {
+ return false;
+ }
+ if ( getMinorVersion() != that.getMinorVersion() )
+ {
+ return false;
+ }
+ if ( getQualifier() != null ? !getQualifier().equals( that.getQualifier() )
+ : that.getQualifier() != null )
+ {
+ return false;
+ }
+
+ return true;
+ }
+ } );
+
+ if ( versions.size() == 1 )
+ {
+ this.version = version;
+ }
+ else
+ {
+ this.version = null;
+ }
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public List getVersions()
+ {
+ List versions = new ArrayList( this.versions );
+ Collections.sort( versions );
+ return versions;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+ }
+
+ public String getRepositoryId()
+ {
+ return repositoryId;
+ }
+
+ public List getMailingLists()
+ {
+ return mailingLists;
+ }
+
+ public String getRepositoryUrlName()
+ {
+ return repositoryUrlName;
+ }
+
+ public List getReports()
+ {
+ return reports;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.xwork.ModelDriven;
+import com.opensymphony.xwork.Preparable;
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.InvalidConfigurationException;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+import org.codehaus.plexus.rbac.profile.RoleProfileManager;
+import org.codehaus.plexus.registry.RegistryException;
+import org.codehaus.plexus.security.rbac.RbacManagerException;
+import org.codehaus.plexus.security.rbac.Resource;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+import java.io.IOException;
+
+/**
+ * Base action for repository configuration actions.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public abstract class AbstractConfigureRepositoryAction
+ extends PlexusActionSupport
+ implements ModelDriven, Preparable, SecureAction
+{
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ /**
+ * @plexus.requirement role-hint="archiva"
+ */
+ protected RoleProfileManager roleProfileManager;
+
+ /**
+ * The repository.
+ */
+ private AbstractRepositoryConfiguration repository;
+
+ /**
+ * The repository ID to lookup when editing a repository.
+ */
+ private String repoId;
+
+ /**
+ * The previously read configuration.
+ */
+ protected Configuration configuration;
+
+ public String add()
+ throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException, RegistryException
+ {
+ // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
+
+ AbstractRepositoryConfiguration existingRepository = getRepository( repository.getId() );
+ if ( existingRepository != null )
+ {
+ addFieldError( "id", "A repository with that id already exists" );
+ return INPUT;
+ }
+
+ return saveConfiguration();
+ }
+
+ public String edit()
+ throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException, RegistryException
+ {
+ // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
+
+ AbstractRepositoryConfiguration existingRepository = getRepository( repository.getId() );
+ removeRepository( existingRepository );
+
+ return saveConfiguration();
+ }
+
+ protected abstract void removeRepository( AbstractRepositoryConfiguration existingRepository );
+
+ protected abstract AbstractRepositoryConfiguration getRepository( String id );
+
+ private String saveConfiguration()
+ throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException, RegistryException
+ {
+ addRepository();
+
+ archivaConfiguration.save( configuration );
+
+ // TODO: do we need to check if indexing is needed?
+
+ addActionMessage( "Successfully saved configuration" );
+
+ return SUCCESS;
+ }
+
+ protected abstract void addRepository()
+ throws IOException, RoleProfileException;
+
+ public String input()
+ {
+ return INPUT;
+ }
+
+ public Object getModel()
+ {
+ return repository;
+ }
+
+ protected abstract AbstractRepositoryConfiguration createRepository();
+
+ public void prepare()
+ {
+ configuration = archivaConfiguration.getConfiguration();
+
+ if ( repository == null )
+ {
+ repository = getRepository( repoId );
+ }
+ if ( repository == null )
+ {
+ repository = createRepository();
+ }
+ }
+
+ public String getRepoId()
+ {
+ return repoId;
+ }
+
+ public void setRepoId( String repoId )
+ {
+ this.repoId = repoId;
+ }
+
+ protected AbstractRepositoryConfiguration getRepository()
+ {
+ return repository;
+ }
+
+ public Configuration getConfiguration()
+ {
+ return configuration;
+ }
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+
+ bundle.setRequiresAuthentication( true );
+
+ if ( getRepoId() != null )
+ {
+ // TODO: this is not right. It needs to change based on method. But is this really the right way to restrict this area?
+ // TODO: not right. We only care about this permission on managed repositories. Otherwise, it's configuration
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY, getRepoId() );
+ }
+ else
+ {
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
+ }
+
+ return bundle;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.InvalidConfigurationException;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.codehaus.plexus.rbac.profile.RoleProfileManager;
+import org.codehaus.plexus.registry.RegistryException;
+import org.codehaus.plexus.security.rbac.Resource;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+import java.io.IOException;
+
+/**
+ * Base action for repository removal actions.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public abstract class AbstractDeleteRepositoryAction
+ extends PlexusActionSupport
+ implements SecureAction
+{
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ /**
+ * The repository ID to lookup when editing a repository.
+ */
+ protected String repoId;
+
+ /**
+ * Which operation to select.
+ */
+ private String operation = "unmodified";
+
+ /**
+ * @plexus.requirement role-hint="archiva"
+ */
+ protected RoleProfileManager roleProfileManager;
+
+ public String execute()
+ throws IOException, InvalidConfigurationException, RegistryException
+ {
+ // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
+
+ if ( "delete-entry".equals( operation ) || "delete-contents".equals( operation ) )
+ {
+ Configuration configuration = archivaConfiguration.getConfiguration();
+
+ AbstractRepositoryConfiguration existingRepository = getRepository( configuration );
+ if ( existingRepository == null )
+ {
+ addActionError( "A repository with that id does not exist" );
+ return ERROR;
+ }
+
+ // TODO: remove from index too!
+
+ removeRepository( configuration, existingRepository );
+
+ archivaConfiguration.save( configuration );
+
+ if ( "delete-contents".equals( operation ) )
+ {
+ removeContents( existingRepository );
+ }
+ }
+
+ return SUCCESS;
+ }
+
+ protected abstract void removeContents( AbstractRepositoryConfiguration existingRepository )
+ throws IOException;
+
+ protected abstract AbstractRepositoryConfiguration getRepository( Configuration configuration );
+
+ protected abstract void removeRepository( Configuration configuration,
+ AbstractRepositoryConfiguration existingRepository );
+
+ public String input()
+ {
+ return INPUT;
+ }
+
+ public String getRepoId()
+ {
+ return repoId;
+ }
+
+ public void setRepoId( String repoId )
+ {
+ this.repoId = repoId;
+ }
+
+ public String getOperation()
+ {
+ return operation;
+ }
+
+ public void setOperation( String operation )
+ {
+ this.operation = operation;
+ }
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+
+ bundle.setRequiresAuthentication( true );
+
+ if ( getRepoId() != null )
+ {
+ // TODO: not right. We only care about this permission on managed repositories. Otherwise, it's configuration
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY, getRepoId() );
+ }
+ else
+ {
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
+ }
+
+ return bundle;
+ }
+
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.xwork.ModelDriven;
+import com.opensymphony.xwork.Preparable;
+import com.opensymphony.xwork.Validateable;
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.InvalidConfigurationException;
+import org.apache.maven.archiva.indexer.RepositoryIndexException;
+import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
+import org.apache.maven.archiva.repositories.ActiveManagedRepositories;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.codehaus.plexus.registry.RegistryException;
+import org.codehaus.plexus.scheduler.CronExpressionValidator;
+import org.codehaus.plexus.security.rbac.Resource;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * Configures the application.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureAction"
+ */
+public class ConfigureAction
+ extends PlexusActionSupport
+ implements ModelDriven, Preparable, Validateable, SecureAction
+{
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ /**
+ * @plexus.requirement
+ */
+ private ActiveManagedRepositories activeRepositories;
+
+ /**
+ * The configuration.
+ */
+ private Configuration configuration;
+
+ private CronExpressionValidator cronValidator;
+
+ private String second = "0";
+
+ private String minute = "0";
+
+ private String hour = "*";
+
+ private String dayOfMonth = "*";
+
+ private String month = "*";
+
+ private String dayOfWeek = "?";
+
+ private String year;
+
+ private String lastIndexingTime;
+
+ public void validate()
+ {
+ //validate cron expression
+ cronValidator = new CronExpressionValidator();
+
+ if ( !cronValidator.validate( getCronExpression() ) )
+ {
+ addActionError( "Invalid Cron Expression" );
+ }
+ }
+
+ public String execute()
+ throws IOException, RepositoryIndexException, RepositoryIndexSearchException, InvalidConfigurationException,
+ RegistryException
+ {
+ // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
+ // TODO: if this is changed, do we move the index or recreate it?
+ configuration.setDataRefreshCronExpression( getCronExpression() );
+
+ // Normalize the path
+ File file = new File( configuration.getIndexPath() );
+ configuration.setIndexPath( file.getCanonicalPath() );
+ if ( !file.exists() )
+ {
+ file.mkdirs();
+ // TODO: error handling when this fails, or is not a directory!
+ }
+
+ // Just double checking that our validation routines line up with what is expected in the configuration
+ assert configuration.isValid();
+
+ archivaConfiguration.save( configuration );
+
+ // TODO: if the repository has changed, we need to check if indexing is needed!
+
+ addActionMessage( "Successfully saved configuration" );
+
+ return SUCCESS;
+ }
+
+ public String input()
+ {
+ String[] cronEx = configuration.getDataRefreshCronExpression().split( " " );
+ int i = 0;
+
+ while ( i < cronEx.length )
+ {
+ switch ( i )
+ {
+ case 0:
+ second = cronEx[i];
+ break;
+ case 1:
+ minute = cronEx[i];
+ break;
+ case 2:
+ hour = cronEx[i];
+ break;
+ case 3:
+ dayOfMonth = cronEx[i];
+ break;
+ case 4:
+ month = cronEx[i];
+ break;
+ case 5:
+ dayOfWeek = cronEx[i];
+ break;
+ case 6:
+ year = cronEx[i];
+ break;
+ }
+ i++;
+ }
+
+ if ( activeRepositories.getLastDataRefreshTime() != 0 )
+ {
+ lastIndexingTime = new Date( activeRepositories.getLastDataRefreshTime() ).toString();
+ }
+ else
+ {
+ lastIndexingTime = "Never been run.";
+ }
+
+ return INPUT;
+ }
+
+ public Object getModel()
+ {
+ return configuration;
+ }
+
+ public void prepare()
+ {
+ configuration = archivaConfiguration.getConfiguration();
+ }
+
+ public String getLastIndexingTime()
+ {
+ return lastIndexingTime;
+ }
+
+ public void setLastIndexingTime( String lastIndexingTime )
+ {
+ this.lastIndexingTime = lastIndexingTime;
+ }
+
+ public String getSecond()
+ {
+ return second;
+ }
+
+ public void setSecond( String second )
+ {
+ this.second = second;
+ }
+
+ public String getMinute()
+ {
+ return minute;
+ }
+
+ public void setMinute( String minute )
+ {
+ this.minute = minute;
+ }
+
+ public String getHour()
+ {
+ return hour;
+ }
+
+ public void setHour( String hour )
+ {
+ this.hour = hour;
+ }
+
+ public String getDayOfMonth()
+ {
+ return dayOfMonth;
+ }
+
+ public void setDayOfMonth( String dayOfMonth )
+ {
+ this.dayOfMonth = dayOfMonth;
+ }
+
+ public String getYear()
+ {
+ return year;
+ }
+
+ public void setYear( String year )
+ {
+ this.year = year;
+ }
+
+ public String getMonth()
+ {
+ return month;
+ }
+
+ public void setMonth( String month )
+ {
+ this.month = month;
+ }
+
+ public String getDayOfWeek()
+ {
+ return dayOfWeek;
+ }
+
+ public void setDayOfWeek( String dayOfWeek )
+ {
+ this.dayOfWeek = dayOfWeek;
+ }
+
+ private String getCronExpression()
+ {
+ return ( second + " " + minute + " " + hour + " " + dayOfMonth + " " + month + " " + dayOfWeek + " " +
+ year ).trim();
+ }
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+
+ bundle.setRequiresAuthentication( true );
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
+
+ return bundle;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.xwork.ModelDriven;
+import com.opensymphony.xwork.Preparable;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.apache.maven.archiva.web.action.AbstractConfiguredAction;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.model.Model;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.shared.app.company.CompanyPomHandler;
+import org.apache.maven.shared.app.configuration.Configuration;
+import org.apache.maven.shared.app.configuration.MavenAppConfiguration;
+import org.codehaus.plexus.registry.RegistryException;
+import org.codehaus.plexus.security.rbac.Resource;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
+
+import java.io.IOException;
+
+/**
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @version $Id: ConfigurationAction.java 480950 2006-11-30 14:58:35Z evenisse $
+ * @plexus.component role="com.opensymphony.xwork.Action"
+ * role-hint="configureAppearance"
+ */
+public class ConfigureAppearanceAction
+ extends AbstractConfiguredAction
+ implements ModelDriven, SecureAction, Preparable
+{
+ /**
+ * @plexus.requirement
+ */
+ private MavenAppConfiguration appConfigurationStore;
+
+ /**
+ * The configuration.
+ */
+ private Configuration configuration;
+
+ private Model companyModel;
+
+ /**
+ * @plexus.requirement
+ */
+ private CompanyPomHandler companyPomHandler;
+
+ public String execute()
+ throws IOException, RegistryException
+ {
+ appConfigurationStore.save( configuration );
+
+ return SUCCESS;
+ }
+
+ public Object getModel()
+ {
+ return configuration;
+ }
+
+ public void prepare()
+ throws ProjectBuildingException, ArtifactMetadataRetrievalException
+ {
+ configuration = appConfigurationStore.getConfiguration();
+
+ companyModel = companyPomHandler.getCompanyPomModel( configuration.getCompanyPom(), createLocalRepository() );
+ }
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+ bundle.setRequiresAuthentication( true );
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
+
+ return bundle;
+ }
+
+ public Model getCompanyModel()
+ {
+ return companyModel;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration;
+
+import java.io.IOException;
+
+/**
+ * Configures the application repositories.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureProxiedRepositoryAction"
+ */
+public class ConfigureProxiedRepositoryAction
+ extends AbstractConfigureRepositoryAction
+{
+ protected void removeRepository( AbstractRepositoryConfiguration existingRepository )
+ {
+ configuration.removeProxiedRepository( (ProxiedRepositoryConfiguration) existingRepository );
+ }
+
+ protected AbstractRepositoryConfiguration getRepository( String id )
+ {
+ return configuration.getProxiedRepositoryById( id );
+ }
+
+ protected void addRepository()
+ throws IOException
+ {
+ ProxiedRepositoryConfiguration repository = (ProxiedRepositoryConfiguration) getRepository();
+
+ configuration.addProxiedRepository( repository );
+ }
+
+ protected AbstractRepositoryConfiguration createRepository()
+ {
+ return new ProxiedRepositoryConfiguration();
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Configures the application repositories.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureRepositoryAction"
+ */
+public class ConfigureRepositoryAction
+ extends AbstractConfigureRepositoryAction
+{
+ protected void removeRepository( AbstractRepositoryConfiguration existingRepository )
+ {
+ configuration.removeRepository( (RepositoryConfiguration) existingRepository );
+ }
+
+ protected AbstractRepositoryConfiguration getRepository( String id )
+ {
+ return configuration.getRepositoryById( id );
+ }
+
+ protected void addRepository()
+ throws IOException, RoleProfileException
+ {
+ RepositoryConfiguration repository = (RepositoryConfiguration) getRepository();
+
+ // Normalize the path
+ File file = new File( repository.getDirectory() );
+ repository.setDirectory( file.getCanonicalPath() );
+ if ( !file.exists() )
+ {
+ file.mkdirs();
+ // TODO: error handling when this fails, or is not a directory!
+ }
+
+ configuration.addRepository( repository );
+
+ // TODO: double check these are configured on start up
+ roleProfileManager.getDynamicRole( "archiva-repository-manager", repository.getId() );
+
+ roleProfileManager.getDynamicRole( "archiva-repository-observer", repository.getId() );
+ }
+
+ protected AbstractRepositoryConfiguration createRepository()
+ {
+ RepositoryConfiguration repository = new RepositoryConfiguration();
+ repository.setIndexed( false );
+ return repository;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.SyncedRepositoryConfiguration;
+
+import java.io.IOException;
+
+/**
+ * Configures the application repositories.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureSyncedRepositoryAction"
+ */
+public class ConfigureSyncedRepositoryAction
+ extends AbstractConfigureRepositoryAction
+{
+ protected void removeRepository( AbstractRepositoryConfiguration existingRepository )
+ {
+ configuration.removeSyncedRepository( (SyncedRepositoryConfiguration) existingRepository );
+ }
+
+ protected AbstractRepositoryConfiguration getRepository( String id )
+ {
+ return configuration.getSyncedRepositoryById( id );
+ }
+
+ protected void addRepository()
+ throws IOException
+ {
+ SyncedRepositoryConfiguration repository = (SyncedRepositoryConfiguration) getRepository();
+
+ configuration.addSyncedRepository( repository );
+ }
+
+ protected AbstractRepositoryConfiguration createRepository()
+ {
+ return new SyncedRepositoryConfiguration();
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration;
+
+import java.io.IOException;
+
+/**
+ * Configures the application repositories.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteProxiedRepositoryAction"
+ */
+public class DeleteProxiedRepositoryAction
+ extends AbstractDeleteRepositoryAction
+{
+ protected AbstractRepositoryConfiguration getRepository( Configuration configuration )
+ {
+ return configuration.getProxiedRepositoryById( repoId );
+ }
+
+ protected void removeRepository( Configuration configuration, AbstractRepositoryConfiguration existingRepository )
+ {
+ configuration.removeProxiedRepository( (ProxiedRepositoryConfiguration) existingRepository );
+ }
+
+ protected void removeContents( AbstractRepositoryConfiguration existingRepository )
+ throws IOException
+ {
+ // TODO! delete it
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.IOException;
+
+/**
+ * Configures the application repositories.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteRepositoryAction"
+ */
+public class DeleteRepositoryAction
+ extends AbstractDeleteRepositoryAction
+{
+ protected AbstractRepositoryConfiguration getRepository( Configuration configuration )
+ {
+ return configuration.getRepositoryById( repoId );
+ }
+
+ protected void removeRepository( Configuration configuration, AbstractRepositoryConfiguration existingRepository )
+ {
+ configuration.removeRepository( (RepositoryConfiguration) existingRepository );
+
+ try
+ {
+ removeRepositoryRoles( existingRepository );
+ }
+ catch ( RoleProfileException e )
+ {
+ getLogger().error( "Error removing user roles associated with repository " + existingRepository.getId() );
+ }
+ }
+
+ protected void removeContents( AbstractRepositoryConfiguration existingRepository )
+ throws IOException
+ {
+ RepositoryConfiguration repository = (RepositoryConfiguration) existingRepository;
+ getLogger().info( "Removing " + repository.getDirectory() );
+ FileUtils.deleteDirectory( repository.getDirectory() );
+ }
+
+ /**
+ * Remove user roles associated with the repository
+ *
+ * @param existingRepository
+ * @throws RoleProfileException
+ */
+ private void removeRepositoryRoles( AbstractRepositoryConfiguration existingRepository )
+ throws RoleProfileException
+ {
+ roleProfileManager.deleteDynamicRole( "archiva-repository-manager", existingRepository.getId() );
+ roleProfileManager.deleteDynamicRole( "archiva-repository-observer", existingRepository.getId() );
+
+ getLogger().info( "removed user roles associated with repository " + existingRepository.getId() );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.SyncedRepositoryConfiguration;
+
+import java.io.IOException;
+
+/**
+ * Configures the application repositories.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteSyncedRepositoryAction"
+ */
+public class DeleteSyncedRepositoryAction
+ extends AbstractDeleteRepositoryAction
+{
+ protected AbstractRepositoryConfiguration getRepository( Configuration configuration )
+ {
+ return configuration.getSyncedRepositoryById( repoId );
+ }
+
+ protected void removeRepository( Configuration configuration, AbstractRepositoryConfiguration existingRepository )
+ {
+ configuration.removeSyncedRepository( (SyncedRepositoryConfiguration) existingRepository );
+ }
+
+ protected void removeContents( AbstractRepositoryConfiguration existingRepository )
+ throws IOException
+ {
+ // TODO! remove the contents
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.xwork.ModelDriven;
+import com.opensymphony.xwork.Preparable;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.apache.maven.archiva.web.action.AbstractConfiguredAction;
+import org.apache.maven.artifact.installer.ArtifactInstallationException;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.model.Model;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.shared.app.company.CompanyPomHandler;
+import org.apache.maven.shared.app.configuration.CompanyPom;
+import org.apache.maven.shared.app.configuration.Configuration;
+import org.apache.maven.shared.app.configuration.MavenAppConfiguration;
+import org.codehaus.plexus.security.rbac.Resource;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
+
+import java.io.IOException;
+
+/**
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @version $Id: ConfigurationAction.java 480950 2006-11-30 14:58:35Z evenisse $
+ * @plexus.component role="com.opensymphony.xwork.Action"
+ * role-hint="editPom"
+ */
+public class EditPomAction
+ extends AbstractConfiguredAction
+ implements ModelDriven, SecureAction, Preparable
+{
+ /**
+ * @plexus.requirement
+ */
+ private MavenAppConfiguration appConfigurationStore;
+
+ /**
+ * The configuration.
+ */
+ private Configuration configuration;
+
+ /**
+ * @plexus.requirement
+ */
+ private CompanyPomHandler companyPomHandler;
+
+ private Model companyModel;
+
+ public String execute()
+ throws IOException, ArtifactInstallationException
+ {
+ // TODO: hack for passed in String[]
+ String[] logo = (String[]) companyModel.getProperties().get( "organization.logo" );
+ if ( logo != null )
+ {
+ companyModel.getProperties().put( "organization.logo", logo[0] );
+ }
+
+ companyPomHandler.save( companyModel, createLocalRepository() );
+
+ return SUCCESS;
+ }
+
+ public Object getModel()
+ {
+ return companyModel;
+ }
+
+ public void prepare()
+ throws ProjectBuildingException, ArtifactMetadataRetrievalException
+ {
+ configuration = appConfigurationStore.getConfiguration();
+
+ CompanyPom companyPom = configuration.getCompanyPom();
+ companyModel = companyPomHandler.getCompanyPomModel( companyPom, createLocalRepository() );
+
+ if ( companyModel == null )
+ {
+ companyModel = new Model();
+ companyModel.setModelVersion( "4.0.0" );
+ companyModel.setPackaging( "pom" );
+
+ if ( companyPom != null )
+ {
+ companyModel.setGroupId( companyPom.getGroupId() );
+ companyModel.setArtifactId( companyPom.getArtifactId() );
+ }
+ }
+ }
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+ bundle.setRequiresAuthentication( true );
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
+
+ return bundle;
+ }
+
+ public Model getCompanyModel()
+ {
+ return companyModel;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.admin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.scheduler.RepositoryTaskScheduler;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.codehaus.plexus.security.rbac.Resource;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
+import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
+import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+
+/**
+ * Configures the application.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="runRepositoryTaskAction"
+ */
+public class RunRepositoryTaskAction
+ extends PlexusActionSupport
+ implements SecureAction
+{
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryTaskScheduler taskScheduler;
+
+ public String runRefresh()
+ throws TaskExecutionException
+ {
+ taskScheduler.runDataRefresh();
+
+ return SUCCESS;
+ }
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+
+ bundle.setRequiresAuthentication( true );
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_RUN_INDEXER, Resource.GLOBAL );
+
+ return bundle;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.action.component;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.web.action.AbstractConfiguredAction;
+import org.apache.maven.model.Model;
+import org.apache.maven.shared.app.company.CompanyPomHandler;
+import org.apache.maven.shared.app.configuration.MavenAppConfiguration;
+
+/**
+ * Stores the company information for displaying on the page.
+ *
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="companyInfo"
+ */
+public class CompanyInfoAction
+ extends AbstractConfiguredAction
+{
+ private String companyLogo;
+
+ private String companyUrl;
+
+ private String companyName;
+
+ /**
+ * @plexus.requirement
+ */
+ private CompanyPomHandler handler;
+
+ /**
+ * @plexus.requirement
+ */
+ private MavenAppConfiguration appConfigurationStore;
+
+ public String execute()
+ throws Exception
+ {
+ Model model = handler.getCompanyPomModel( appConfigurationStore.getConfiguration().getCompanyPom(),
+ createLocalRepository() );
+
+ if ( model != null )
+ {
+ if ( model.getOrganization() != null )
+ {
+ companyName = model.getOrganization().getName();
+ companyUrl = model.getOrganization().getUrl();
+ }
+
+ companyLogo = model.getProperties().getProperty( "organization.logo" );
+ }
+
+ return SUCCESS;
+ }
+
+ public String getCompanyLogo()
+ {
+ return companyLogo;
+ }
+
+ public String getCompanyUrl()
+ {
+ return companyUrl;
+ }
+
+ public String getCompanyName()
+ {
+ return companyName;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.apache.maven.archiva.web.check;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.rbac.profile.RoleProfileException;
+import org.codehaus.plexus.rbac.profile.RoleProfileManager;
+import org.codehaus.plexus.security.system.check.EnvironmentCheck;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * RoleExistanceEnvironmentCheck:
+ * <p/>
+ * Under certain circumstances it is possible that the user store and/or role store
+ * have been wiped or reset and its important to see if there are repositories already
+ * configured in archiva that need to reinitialized in terms of having their roles created.
+ *
+ * @author: Jesse McConnell <jmcconnell@apache.org>
+ * @version: $ID:
+ * @plexus.component role="org.codehaus.plexus.security.system.check.EnvironmentCheck"
+ * role-hint="repository-role-check"
+ */
+public class RoleExistanceEnvironmentCheck
+ extends AbstractLogEnabled
+ implements EnvironmentCheck
+{
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ /**
+ * @plexus.requirement role-hint="archiva"
+ */
+ private RoleProfileManager roleProfileManager;
+
+ private boolean checked;
+
+ public void validateEnvironment( List list )
+ {
+ if ( !checked )
+ {
+ try
+ {
+ // check if there is potential for role/repo disconnect
+ Configuration configuration = archivaConfiguration.getConfiguration();
+ if ( configuration.isValid() )
+ {
+ List repos = configuration.getRepositories();
+
+ for ( Iterator i = repos.iterator(); i.hasNext(); )
+ {
+ RepositoryConfiguration repository = (RepositoryConfiguration) i.next();
+
+ roleProfileManager.getDynamicRole( "archiva-repository-manager", repository.getId() );
+
+ roleProfileManager.getDynamicRole( "archiva-repository-observer", repository.getId() );
+ }
+ }
+ }
+ catch ( RoleProfileException rpe )
+ {
+ list.add( this.getClass().getName() + "error initializing roles: " + rpe.getMessage() );
+ getLogger().info( "error initializing roles", rpe );
+ }
+
+ checked = true;
+ }
+ }
+
+}
--- /dev/null
+package org.apache.maven.archiva.web.interceptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.interceptor.Interceptor;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+
+/**
+ * An interceptor that makes the application configuration available
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @plexus.component role="com.opensymphony.xwork.interceptor.Interceptor"
+ * role-hint="configurationInterceptor"
+ */
+public class ConfigurationInterceptor
+ extends AbstractLogEnabled
+ implements Interceptor
+{
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ /**
+ * @param actionInvocation
+ * @return
+ * @throws Exception
+ */
+ public String intercept( ActionInvocation actionInvocation )
+ throws Exception
+ {
+ Configuration configuration = archivaConfiguration.getConfiguration();
+
+ if ( !configuration.isValid() )
+ {
+ if ( configuration.getRepositories().isEmpty() )
+ {
+ getLogger().info( "No repositories were configured - forwarding to repository configuration page" );
+ return "config-repository-needed";
+ }
+ else
+ {
+ getLogger().info( "Configuration is incomplete - forwarding to configuration page" );
+ return "config-needed";
+ }
+ }
+ else
+ {
+ return actionInvocation.invoke();
+ }
+ }
+
+ public void destroy()
+ {
+ // This space left intentionally blank
+ }
+
+ public void init()
+ {
+ // This space left intentionally blank
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.mapper;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
+import com.opensymphony.webwork.dispatcher.mapper.DefaultActionMapper;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Map alternate URLs to specific actions. Used for the repository browser and the proxy.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class RepositoryActionMapper
+ extends DefaultActionMapper
+{
+ private static final String BROWSE_PREFIX = "/browse/";
+
+ private static final String PROXY_PREFIX = "/proxy/";
+
+ public String getUriFromActionMapping( ActionMapping actionMapping )
+ {
+ Map params = actionMapping.getParams();
+ if ( "browseGroup".equals( actionMapping.getName() ) )
+ {
+ return BROWSE_PREFIX + params.remove( "groupId" );
+ }
+ else if ( "browseArtifact".equals( actionMapping.getName() ) )
+ {
+ return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" );
+ }
+ else if ( "showArtifact".equals( actionMapping.getName() ) )
+ {
+ return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
+ params.remove( "version" );
+ }
+ else if ( "showArtifactDependencies".equals( actionMapping.getName() ) )
+ {
+ return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
+ params.remove( "version" ) + "/dependencies";
+ }
+ else if ( "showArtifactMailingLists".equals( actionMapping.getName() ) )
+ {
+ return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
+ params.remove( "version" ) + "/mailingLists";
+ }
+ else if ( "showArtifactDependees".equals( actionMapping.getName() ) )
+ {
+ return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
+ params.remove( "version" ) + "/usedby";
+ }
+ else if ( "showArtifactDependencyTree".equals( actionMapping.getName() ) )
+ {
+ return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
+ params.remove( "version" ) + "/dependencyTree";
+ }
+ else if ( "proxy".equals( actionMapping.getName() ) )
+ {
+ return PROXY_PREFIX + params.remove( "path" );
+ }
+
+ return super.getUriFromActionMapping( actionMapping );
+ }
+
+ public ActionMapping getMapping( HttpServletRequest httpServletRequest )
+ {
+ String path = httpServletRequest.getServletPath();
+ if ( path.startsWith( BROWSE_PREFIX ) )
+ {
+ path = path.substring( BROWSE_PREFIX.length() );
+ if ( path.length() == 0 )
+ {
+ return new ActionMapping( "browse", "/", "", null );
+ }
+ else
+ {
+ String[] parts = path.split( "/" );
+ if ( parts.length == 1 )
+ {
+ Map params = new HashMap();
+ params.put( "groupId", parts[0] );
+ return new ActionMapping( "browseGroup", "/", "", params );
+ }
+ else if ( parts.length == 2 )
+ {
+ Map params = new HashMap();
+ params.put( "groupId", parts[0] );
+ params.put( "artifactId", parts[1] );
+ return new ActionMapping( "browseArtifact", "/", "", params );
+ }
+ else if ( parts.length == 3 )
+ {
+ Map params = new HashMap();
+ params.put( "groupId", parts[0] );
+ params.put( "artifactId", parts[1] );
+ params.put( "version", parts[2] );
+ return new ActionMapping( "showArtifact", "/", "", params );
+ }
+ else if ( parts.length == 4 )
+ {
+ Map params = new HashMap();
+ params.put( "groupId", parts[0] );
+ params.put( "artifactId", parts[1] );
+ params.put( "version", parts[2] );
+
+ if ( "dependencies".equals( parts[3] ) )
+ {
+ return new ActionMapping( "showArtifactDependencies", "/", "", params );
+ }
+ else if ( "mailingLists".equals( parts[3] ) )
+ {
+ return new ActionMapping( "showArtifactMailingLists", "/", "", params );
+ }
+ else if ( "usedby".equals( parts[3] ) )
+ {
+ return new ActionMapping( "showArtifactDependees", "/", "", params );
+ }
+ else if ( "dependencyTree".equals( parts[3] ) )
+ {
+ return new ActionMapping( "showArtifactDependencyTree", "/", "", params );
+ }
+ }
+ }
+ }
+ else if ( path.startsWith( PROXY_PREFIX ) )
+ {
+ // retain the leading /
+ path = path.substring( PROXY_PREFIX.length() - 1 );
+
+ Map params = new HashMap();
+ params.put( "path", path );
+ return new ActionMapping( "proxy", "/", "", params );
+ }
+
+ return super.getMapping( httpServletRequest );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.commons.lang.StringUtils;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.webdav.DavServerComponent;
+import org.codehaus.plexus.webdav.DavServerListener;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * AuditLog - Audit Log.
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.web.repository.AuditLog"
+ */
+public class AuditLog
+ implements DavServerListener, Initializable
+{
+ public static final String ROLE = AuditLog.class.getName();
+
+ /**
+ * @plexus.configuration default-value="${appserver.base}/logs/audit.log"
+ */
+ private File logFile;
+
+ /**
+ * @plexus.configuration default-value="yyyy-MM-dd HH:mm:ss"
+ */
+ private String timestampFormat;
+
+ private PrintWriter writer;
+
+ private SimpleDateFormat timestamp;
+
+ private String getServerId( DavServerComponent server )
+ {
+ return "[" + server.getPrefix() + "]";
+ }
+
+ public void serverCollectionCreated( DavServerComponent server, String resource )
+ {
+ log( getServerId( server ) + " Created Directory \"" + resource + "\"" );
+ }
+
+ public void serverCollectionRemoved( DavServerComponent server, String resource )
+ {
+ log( getServerId( server ) + " Removed Directory \"" + resource + "\"" );
+ }
+
+ public void serverResourceCreated( DavServerComponent server, String resource )
+ {
+ log( getServerId( server ) + " Created File \"" + resource + "\"" );
+ }
+
+ public void serverResourceModified( DavServerComponent server, String resource )
+ {
+ log( getServerId( server ) + " Modified Existing File \"" + resource + "\"" );
+ }
+
+ public void serverResourceRemoved( DavServerComponent server, String resource )
+ {
+ log( getServerId( server ) + " Removed File \"" + resource + "\"" );
+ }
+
+ /**
+ * Log the message to the file.
+ *
+ * @param msg the message.
+ */
+ public void log( String msg )
+ {
+ // Synchronize to prevent threading issues.
+ synchronized ( writer )
+ {
+ writer.println( timestamp.format( new Date() ) + " - " + msg );
+ // Manually flush buffer to ensure data is written to disk.
+ writer.flush();
+ }
+ }
+
+ public void initialize()
+ throws InitializationException
+ {
+ File parentDir = logFile.getParentFile();
+ if ( parentDir != null )
+ {
+ if ( !parentDir.exists() )
+ {
+ parentDir.mkdirs();
+ }
+ }
+
+ if ( StringUtils.isBlank( timestampFormat ) )
+ {
+ timestampFormat = "yyyy-MM-dd HH:mm:ss";
+ }
+
+ timestamp = new SimpleDateFormat( timestampFormat );
+
+ try
+ {
+ writer = new PrintWriter( new FileWriter( logFile ) );
+ log( "Logging Initialized." );
+ }
+ catch ( IOException e )
+ {
+ throw new InitializationException( "Unable to initialize log file writer: " + logFile.getAbsolutePath(), e );
+ }
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.Proxy;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.apache.maven.archiva.proxy.ProxyException;
+import org.apache.maven.archiva.proxy.ProxyRequestHandler;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.codehaus.plexus.webdav.AbstractDavServerComponent;
+import org.codehaus.plexus.webdav.DavServerComponent;
+import org.codehaus.plexus.webdav.DavServerException;
+import org.codehaus.plexus.webdav.servlet.DavServerRequest;
+import org.codehaus.plexus.webdav.util.WebdavMethodUtil;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * ProxiedDavServer
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ * @plexus.component role="org.codehaus.plexus.webdav.DavServerComponent"
+ * role-hint="proxied"
+ * instantiation-strategy="per-lookup"
+ */
+public class ProxiedDavServer
+ extends AbstractDavServerComponent
+{
+ /**
+ * @plexus.requirement role-hint="simple"
+ */
+ private DavServerComponent davServer;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
+
+ /**
+ * @plexus.requirement role="org.apache.maven.archiva.proxy.ProxyRequestHandler"
+ * @todo seems to be a bug in qdox that the role above is required
+ */
+ private ProxyRequestHandler proxyRequestHandler;
+
+ /**
+ * @plexus.requirement
+ */
+ private ConfiguredRepositoryFactory repositoryFactory;
+
+ private RepositoryConfiguration repositoryConfiguration;
+
+ private ArtifactRepository managedRepository;
+
+ private List/*<ArtifactRepository>*/proxiedRepositories;
+
+ private ProxyInfo wagonProxy;
+
+ public String getPrefix()
+ {
+ return davServer.getPrefix();
+ }
+
+ public File getRootDirectory()
+ {
+ return davServer.getRootDirectory();
+ }
+
+ public void setPrefix( String prefix )
+ {
+ davServer.setPrefix( prefix );
+ }
+
+ public void setRootDirectory( File rootDirectory )
+ {
+ davServer.setRootDirectory( rootDirectory );
+ }
+
+ public void init( ServletConfig servletConfig )
+ throws DavServerException
+ {
+ davServer.init( servletConfig );
+
+ proxiedRepositories = new ArrayList();
+
+ Configuration config = archivaConfiguration.getConfiguration();
+
+ wagonProxy = createWagonProxy( config.getProxy() );
+
+ repositoryConfiguration = config.getRepositoryByUrlName( getPrefix() );
+
+ managedRepository = repositoryFactory.createRepository( repositoryConfiguration );
+
+ for ( Iterator i = config.getProxiedRepositories().iterator(); i.hasNext(); )
+ {
+ ProxiedRepositoryConfiguration proxiedRepoConfig = (ProxiedRepositoryConfiguration) i.next();
+
+ if ( proxiedRepoConfig.getManagedRepository().equals( repositoryConfiguration.getId() ) )
+ {
+ proxiedRepositories.add( repositoryFactory.createProxiedRepository( proxiedRepoConfig ) );
+ }
+ }
+ }
+
+ public void process( DavServerRequest request, HttpServletResponse response )
+ throws DavServerException, ServletException, IOException
+ {
+ if ( WebdavMethodUtil.isReadMethod( request.getRequest().getMethod() ) )
+ {
+ if ( !hasResource( request.getLogicalResource() ) )
+ {
+ fetchContentFromProxies( request );
+ }
+ }
+
+ davServer.process( request, response );
+ }
+
+ private void fetchContentFromProxies( DavServerRequest request )
+ throws ServletException
+ {
+ try
+ {
+ proxyRequestHandler.get( request.getLogicalResource(), this.proxiedRepositories, this.managedRepository,
+ this.wagonProxy );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ // TODO: getLogger().info( "Unable to fetch resource, it does not exist.", e );
+ // return an HTTP 404 instead of HTTP 500 error.
+ return;
+ }
+ catch ( ProxyException e )
+ {
+ throw new ServletException( "Unable to fetch resource.", e );
+ }
+ }
+
+ private ProxyInfo createWagonProxy( Proxy proxy )
+ {
+ ProxyInfo proxyInfo = null;
+ if ( proxy != null && StringUtils.isNotEmpty( proxy.getHost() ) )
+ {
+ proxyInfo = new ProxyInfo();
+ proxyInfo.setHost( proxy.getHost() );
+ proxyInfo.setPort( proxy.getPort() );
+ proxyInfo.setUserName( proxy.getUsername() );
+ proxyInfo.setPassword( proxy.getPassword() );
+ proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
+ proxyInfo.setType( proxy.getProtocol() );
+ }
+ return proxyInfo;
+ }
+
+ public RepositoryConfiguration getRepositoryConfiguration()
+ {
+ return repositoryConfiguration;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.codehaus.plexus.registry.Registry;
+import org.codehaus.plexus.registry.RegistryListener;
+import org.codehaus.plexus.security.authentication.AuthenticationException;
+import org.codehaus.plexus.security.authentication.AuthenticationResult;
+import org.codehaus.plexus.security.authorization.AuthorizationException;
+import org.codehaus.plexus.security.authorization.AuthorizationResult;
+import org.codehaus.plexus.security.policy.AccountLockedException;
+import org.codehaus.plexus.security.policy.MustChangePasswordException;
+import org.codehaus.plexus.security.system.SecuritySession;
+import org.codehaus.plexus.security.system.SecuritySystem;
+import org.codehaus.plexus.security.ui.web.filter.authentication.HttpAuthenticator;
+import org.codehaus.plexus.webdav.DavServerComponent;
+import org.codehaus.plexus.webdav.DavServerException;
+import org.codehaus.plexus.webdav.servlet.DavServerRequest;
+import org.codehaus.plexus.webdav.servlet.multiplexed.MultiplexedWebDavServlet;
+import org.codehaus.plexus.webdav.util.WebdavMethodUtil;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * RepositoryServlet
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class RepositoryServlet
+ extends MultiplexedWebDavServlet
+ implements RegistryListener
+{
+ /**
+ * @plexus.requirement
+ */
+ private SecuritySystem securitySystem;
+
+ /**
+ * @plexus.requirement role-hint="basic"
+ */
+ private HttpAuthenticator httpAuth;
+
+ /**
+ * @plexus.requirement
+ */
+ private AuditLog audit;
+
+ private Configuration configuration;
+
+ private ArchivaConfiguration archivaConfiguration;
+
+ public void initComponents()
+ throws ServletException
+ {
+ super.initComponents();
+
+ securitySystem = (SecuritySystem) lookup( SecuritySystem.ROLE );
+ httpAuth = (HttpAuthenticator) lookup( HttpAuthenticator.ROLE, "basic" );
+ audit = (AuditLog) lookup( AuditLog.ROLE );
+
+ archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class.getName() );
+ configuration = archivaConfiguration.getConfiguration();
+ archivaConfiguration.addChangeListener( this );
+ }
+
+ public void initServers( ServletConfig servletConfig )
+ throws DavServerException
+ {
+ List repositories = configuration.getRepositories();
+ Iterator itrepos = repositories.iterator();
+ while ( itrepos.hasNext() )
+ {
+ RepositoryConfiguration repoConfig = (RepositoryConfiguration) itrepos.next();
+ File repoDir = new File( repoConfig.getDirectory() );
+
+ if ( !repoDir.exists() )
+ {
+ repoDir.mkdirs();
+ }
+
+ DavServerComponent server = createServer( repoConfig.getUrlName(), repoDir, servletConfig );
+
+ server.addListener( audit );
+ }
+ }
+
+ public RepositoryConfiguration getRepositoryConfiguration( DavServerRequest request )
+ {
+ return configuration.getRepositoryByUrlName( request.getPrefix() );
+ }
+
+ public String getRepositoryName( DavServerRequest request )
+ {
+ RepositoryConfiguration repoConfig = getRepositoryConfiguration( request );
+ if ( repoConfig == null )
+ {
+ return "Unknown";
+ }
+
+ return repoConfig.getName();
+ }
+
+ public boolean isAuthenticated( DavServerRequest davRequest, HttpServletResponse response )
+ throws ServletException, IOException
+ {
+ HttpServletRequest request = davRequest.getRequest();
+
+ // Authentication Tests.
+ try
+ {
+ AuthenticationResult result = httpAuth.getAuthenticationResult( request, response );
+
+ if ( ( result != null ) && !result.isAuthenticated() )
+ {
+ // Must Authenticate.
+ httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
+ new AuthenticationException( "User Credentials Invalid" ) );
+ return false;
+ }
+
+ }
+ catch ( AuthenticationException e )
+ {
+ log( "Fatal Http Authentication Error.", e );
+ throw new ServletException( "Fatal Http Authentication Error.", e );
+ }
+ catch ( AccountLockedException e )
+ {
+ httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
+ new AuthenticationException( "User account is locked" ) );
+ }
+ catch ( MustChangePasswordException e )
+ {
+ httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
+ new AuthenticationException( "You must change your password." ) );
+ }
+
+ return true;
+ }
+
+ public boolean isAuthorized( DavServerRequest davRequest, HttpServletResponse response )
+ throws ServletException, IOException
+ {
+ // Authorization Tests.
+ HttpServletRequest request = davRequest.getRequest();
+
+ boolean isWriteRequest = WebdavMethodUtil.isWriteMethod( request.getMethod() );
+
+ SecuritySession securitySession = httpAuth.getSecuritySession();
+ try
+ {
+ String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
+
+ if ( isWriteRequest )
+ {
+ permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
+ }
+
+ AuthorizationResult authzResult =
+ securitySystem.authorize( securitySession, permission, getRepositoryConfiguration( davRequest )
+ .getId() );
+
+ if ( !authzResult.isAuthorized() )
+ {
+ if ( authzResult.getException() != null )
+ {
+ log( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest +
+ ",permission=" + permission + "] : " + authzResult.getException().getMessage() );
+ }
+
+ // Issue HTTP Challenge.
+ httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
+ new AuthenticationException( "Authorization Denied." ) );
+ return false;
+ }
+ }
+ catch ( AuthorizationException e )
+ {
+ throw new ServletException( "Fatal Authorization Subsystem Error." );
+ }
+
+ return true;
+ }
+
+ public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+ {
+ // nothing to do
+ }
+
+ public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
+ {
+ configuration = archivaConfiguration.getConfiguration();
+
+ if ( propertyName.startsWith( "repositories" ) )
+ {
+ log( "Triggering managed repository configuration change with " + propertyName + " set to " +
+ propertyValue );
+ getDavManager().removeAllServers();
+
+ try
+ {
+ initServers( getServletConfig() );
+ }
+ catch ( DavServerException e )
+ {
+ log( "Error restarting WebDAV server after configuration change - service disabled: " + e.getMessage(),
+ e );
+ }
+ }
+ else
+ {
+ log( "Not triggering managed repository configuration change with " + propertyName );
+ }
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.tags;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.webwork.WebWorkException;
+import com.opensymphony.webwork.components.Component;
+import com.opensymphony.xwork.util.OgnlValueStack;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.common.artifact.managed.ManagedArtifact;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.apache.maven.archiva.repositories.ActiveManagedRepositories;
+import org.apache.maven.project.ProjectBuildingException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.PageContext;
+
+/**
+ * DownloadArtifact
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="com.opensymphony.webwork.components.Component" role-hint="download-artifact"
+ * instantiation-strategy="per-lookup"
+ */
+public class DownloadArtifact
+ extends Component
+{
+ /**
+ * @plexus.requirement
+ */
+ private ActiveManagedRepositories managedRepositories;
+
+ private HttpServletRequest req;
+
+ private HttpServletResponse res;
+
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ private boolean mini = false;
+
+ public DownloadArtifact( OgnlValueStack stack, PageContext pageContext )
+ {
+ super( stack );
+ this.req = (HttpServletRequest) pageContext.getRequest();
+ this.res = (HttpServletResponse) pageContext.getResponse();
+ try
+ {
+ managedRepositories = (ActiveManagedRepositories) PlexusTagUtil.lookup( pageContext,
+ ActiveManagedRepositories.ROLE );
+ }
+ catch ( ComponentLookupException e )
+ {
+ throw new RuntimeException( e.getMessage(), e );
+ }
+ }
+
+ public boolean end( Writer writer, String body )
+ {
+ StringBuffer sb = new StringBuffer();
+
+ try
+ {
+ ManagedArtifact managedArtifact = managedRepositories.findArtifact( groupId, artifactId, version );
+
+ if ( managedArtifact != null )
+ {
+ RepositoryConfiguration repoConfig = managedRepositories.getRepositoryConfiguration( managedArtifact
+ .getRepositoryId() );
+ String prefix = req.getContextPath() + "/repository/" + repoConfig.getUrlName();
+
+ if ( mini )
+ {
+ appendMini( sb, prefix, managedArtifact );
+ }
+ else
+ {
+ appendNormal( sb, prefix, managedArtifact );
+ }
+ }
+ }
+ catch ( ProjectBuildingException e )
+ {
+ appendError( sb, e );
+ }
+
+ try
+ {
+ writer.write( sb.toString() );
+ }
+ catch ( IOException e )
+ {
+ throw new WebWorkException( "IOError: " + e.getMessage(), e );
+ }
+
+ return super.end( writer, body );
+ }
+
+ private void appendError( StringBuffer sb, ProjectBuildingException e )
+ {
+ /* do nothing */
+ }
+
+ private void appendMini( StringBuffer sb, String prefix, ManagedArtifact managedArtifact )
+ {
+ /* do nothing */
+ }
+
+ private void appendNormal( StringBuffer sb, String prefix, ManagedArtifact managedArtifact )
+ {
+ /*
+ * <div class="download">
+ * <div class="hd">
+ * <div class="c"></div>
+ * </div>
+ * <div class="bd">
+ * <div class="c">
+ * <-- main content goes here -->
+ * </div>
+ * </div>
+ * <div class="ft">
+ * <div class="c"></div>
+ * </div>
+ * </div>
+ */
+
+ sb.append( "<div class=\"download\">" );
+ sb.append( "<div class=\"hd\"><div class=\"c\"></div></div>" );
+ sb.append( "<div class=\"bd\"><div class=\"c\">" );
+
+ // Heading
+ sb.append( "<h2>" );
+ if ( managedArtifact.getAttached().isEmpty() )
+ {
+ sb.append( "Download" );
+ }
+ else
+ {
+ sb.append( "Downloads" );
+ }
+ sb.append( "</h2>" );
+
+ // Body
+ sb.append( "<p class=\"body\">" );
+
+ appendLink( sb, prefix, managedArtifact.getPath(), "main" );
+
+ Iterator it = managedArtifact.getAttached().entrySet().iterator();
+ while ( it.hasNext() )
+ {
+ Map.Entry entry = (Entry) it.next();
+ String type = (String) entry.getKey();
+ String path = (String) entry.getValue();
+
+ if ( StringUtils.isNotBlank( path ) )
+ {
+ sb.append( "<br/>" );
+ appendLink( sb, prefix, path, type );
+ }
+ }
+
+ sb.append( "</div>" ); // close "downloadbox.bd.c"
+ sb.append( "</div>" ); // close "downloadbox.bd"
+
+ sb.append( "<div class=\"ft\"><div class=\"c\"></div></div>" );
+ sb.append( "</div>" ); // close "download"
+ }
+
+ private void appendLink( StringBuffer sb, String prefix, String path, String type )
+ {
+ StringBuffer url = new StringBuffer();
+
+ url.append( prefix );
+ url.append( "/" ).append( path );
+
+ String filename = path.substring( path.lastIndexOf( "/" ) + 1 );
+
+ sb.append( "<a href=\"" ).append( StringEscapeUtils.escapeXml( url.toString() ) ).append( "\"" );
+ sb.append( " title=\"" ).append( "Download " ).append( StringEscapeUtils.escapeXml( filename ) ).append( "\"" );
+ sb.append( ">" );
+
+ sb.append( "<img src=\"" ).append( req.getContextPath() );
+ sb.append( "/images/download-type-" ).append( type ).append( ".png\" />" );
+
+ // TODO: Include file size / date in output ?
+ sb.append( StringUtils.capitalize( type ) );
+ sb.append( "</a>" );
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public void setMini( boolean mini )
+ {
+ this.mini = mini;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.tags;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.webwork.views.jsp.TagUtils;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.TagSupport;
+
+/**
+ * DownloadArtifactTag
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class DownloadArtifactTag
+ extends TagSupport
+{
+ private String groupId_; // stores EL-based groupId property
+
+ private String groupId; // stores the evaluated groupId object.
+
+ private String artifactId_; // stores EL-based artifactId property
+
+ private String artifactId; // stores the evaluated artifactId object.
+
+ private String version_; // stores EL-based version property
+
+ private String version; // stores the evaluated version object.
+
+ private String mini_; // stores EL-based mini property
+
+ private boolean mini; // stores the evaluated mini object.
+
+ public int doEndTag()
+ throws JspException
+ {
+ evaluateExpressions();
+
+ DownloadArtifact download = new DownloadArtifact( TagUtils.getStack( pageContext ), pageContext );
+ download.setGroupId( groupId );
+ download.setArtifactId( artifactId );
+ download.setVersion( version );
+ download.setMini( mini );
+
+ download.end( pageContext.getOut(), "" );
+
+ return super.doEndTag();
+ }
+
+ private void evaluateExpressions()
+ throws JspException
+ {
+ ExpressionTool exprTool = new ExpressionTool( pageContext, this, "download" );
+
+ // Handle required properties.
+ groupId = exprTool.requiredString( "groupId", groupId_ );
+ artifactId = exprTool.requiredString( "artifactId", artifactId_ );
+ version = exprTool.requiredString( "version", version_ );
+
+ // Handle optional properties
+ mini = exprTool.optionalBoolean( "mini", mini_, false );
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId_ = artifactId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId_ = groupId;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version_ = version;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.tags;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.taglibs.standard.tag.common.core.NullAttributeException;
+import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.Tag;
+
+/**
+ * ExpressionTool
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class ExpressionTool
+{
+ private PageContext pageContext;
+
+ private Tag tag;
+
+ private String tagName;
+
+ public ExpressionTool( PageContext pageContext, Tag tag, String tagName )
+ {
+ this.pageContext = pageContext;
+ this.tag = tag;
+ this.tagName = tagName;
+ }
+
+ public boolean optionalBoolean( String propertyName, String expression, boolean defaultValue )
+ throws JspException
+ {
+ try
+ {
+ Boolean ret = (Boolean) ExpressionUtil.evalNotNull( this.tagName, propertyName, expression, Boolean.class,
+ this.tag, this.pageContext );
+
+ if ( ret == null )
+ {
+ return defaultValue;
+ }
+
+ return ret.booleanValue();
+ }
+ catch ( NullAttributeException e )
+ {
+ return defaultValue;
+ }
+ }
+
+ public String optionalString( String propertyName, String expression, String defaultValue )
+ throws JspException
+ {
+ try
+ {
+ String ret = (String) ExpressionUtil.evalNotNull( this.tagName, propertyName, expression, String.class,
+ this.tag, this.pageContext );
+
+ if ( ret == null )
+ {
+ return defaultValue;
+ }
+
+ return ret;
+ }
+ catch ( NullAttributeException e )
+ {
+ return defaultValue;
+ }
+ }
+
+ public String requiredString( String propertyName, String expression )
+ throws JspException
+ {
+ try
+ {
+ String ret = (String) ExpressionUtil.evalNotNull( this.tagName, propertyName, expression, String.class,
+ this.tag, this.pageContext );
+ return ret;
+ }
+ catch ( NullAttributeException e )
+ {
+ String emsg = "Required " + this.tagName + " property [" + propertyName + "] is null!";
+
+ log( emsg, e );
+ throw new JspException( emsg );
+ }
+ }
+
+ private void log( String msg, Throwable t )
+ {
+ pageContext.getServletContext().log( msg, t );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.tags;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.webwork.WebWorkException;
+import com.opensymphony.webwork.components.Component;
+import com.opensymphony.xwork.util.OgnlValueStack;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.StringTokenizer;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * GroupIdLink
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class GroupIdLink
+ extends Component
+{
+ private static final String ACTION = "browseGroup";
+
+ private static final String NAMESPACE = "/";
+
+ private static final boolean includeContext = true;
+
+ private static final boolean encode = true;
+
+ private static final String method = null;
+
+ private HttpServletRequest req;
+
+ private HttpServletResponse res;
+
+ private String groupId;
+
+ private boolean includeTop = false;
+
+ public GroupIdLink( OgnlValueStack stack, HttpServletRequest req, HttpServletResponse res )
+ {
+ super( stack );
+ this.req = req;
+ this.res = res;
+ }
+
+ public boolean end( Writer writer, String body )
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append( "<span class=\"groupId\">" );
+
+ if ( includeTop )
+ {
+ sb.append( "<a href=\"" );
+ sb.append( determineBrowseActionUrl() );
+ sb.append( "\">[top]</a> / " ); // TODO: i18n
+ }
+
+ StringTokenizer tok = new StringTokenizer( groupId, "." );
+ String cumulativeGroup = null;
+
+ while ( tok.hasMoreTokens() )
+ {
+ String token = tok.nextToken();
+
+ if ( cumulativeGroup == null )
+ {
+ cumulativeGroup = token;
+ }
+ else
+ {
+ cumulativeGroup += "." + token;
+ }
+ sb.append( "<a href=\"" );
+ sb.append( determineBrowseGroupActionUrl( cumulativeGroup ) );
+ sb.append( "\">" ).append( token ).append( "</a> / " );
+ }
+
+ sb.append( "</span>" );
+
+ try
+ {
+ writer.write( sb.toString() );
+ }
+ catch ( IOException e )
+ {
+ throw new WebWorkException( "IOError: " + e.getMessage(), e );
+ }
+
+ return super.end( writer, body );
+ }
+
+ private String determineBrowseActionUrl()
+ {
+ return determineActionURL( "browse", NAMESPACE, method, req, res, parameters, req.getScheme(), includeContext,
+ encode );
+ }
+
+ private String determineBrowseGroupActionUrl( String gid )
+ {
+ parameters.put( "groupId", gid );
+
+ return determineActionURL( ACTION, NAMESPACE, method, req, res, parameters, req.getScheme(), includeContext,
+ encode );
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public boolean isIncludeTop()
+ {
+ return includeTop;
+ }
+
+ public void setIncludeTop( boolean includeTop )
+ {
+ this.includeTop = includeTop;
+ }
+
+}
--- /dev/null
+package org.apache.maven.archiva.web.tags;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.webwork.views.jsp.TagUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.TagSupport;
+
+/**
+ * GroupIdLink
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class GroupIdLinkTag
+ extends TagSupport
+{
+ private String var_; // stores EL-based property
+
+ private String var; // stores the evaluated object.
+
+ private boolean includeTop = false;
+
+ public void release()
+ {
+ var_ = null;
+ var = null;
+ includeTop = false;
+
+ super.release();
+ }
+
+ public int doEndTag()
+ throws JspException
+ {
+ evaluateExpressions();
+
+ GroupIdLink gidlink = new GroupIdLink( TagUtils.getStack( pageContext ), (HttpServletRequest) pageContext
+ .getRequest(), (HttpServletResponse) pageContext.getResponse() );
+
+ gidlink.setGroupId( var );
+ gidlink.setIncludeTop( includeTop );
+
+ gidlink.end( pageContext.getOut(), "" );
+
+ return super.doEndTag();
+ }
+
+ private void evaluateExpressions()
+ throws JspException
+ {
+ ExpressionTool exprTool = new ExpressionTool( pageContext, this, "groupIdLink" );
+
+ var = exprTool.optionalString( "var", var_, "" );
+ }
+
+ public void setVar( String value )
+ {
+ this.var_ = value;
+ }
+
+ public void setIncludeTop( boolean includeTop )
+ {
+ this.includeTop = includeTop;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.tags;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.jsp.PageContext;
+
+/**
+ * PlexusTagUtil
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PlexusTagUtil
+{
+ public static Object lookup( PageContext pageContext, String role )
+ throws ComponentLookupException
+ {
+ return getContainer( pageContext ).lookup( role );
+ }
+
+ public static Object lookup( PageContext pageContext, String role, String hint )
+ throws ComponentLookupException
+ {
+ return getContainer( pageContext ).lookup( role, hint );
+ }
+
+ public static PlexusContainer getContainer( PageContext pageContext )
+ throws ComponentLookupException
+ {
+ ServletContext servletContext = pageContext.getServletContext();
+
+ PlexusContainer xworkContainer = (PlexusContainer) servletContext.getAttribute( "webwork.plexus.container" );
+
+ if ( xworkContainer != null )
+ {
+ servletContext.setAttribute( PlexusConstants.PLEXUS_KEY, xworkContainer );
+
+ return xworkContainer;
+ }
+
+ PlexusContainer container = (PlexusContainer) servletContext.getAttribute( PlexusConstants.PLEXUS_KEY );
+ if ( container == null )
+ {
+ throw new ComponentLookupException( "PlexusContainer is null." );
+ }
+ return container;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.maven.archiva.indexer.record.StandardArtifactIndexRecord;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.model.Dependency;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class VersionMerger
+{
+
+ public static List /*<DependencyWrapper>*/ wrap( List /*<StandardArtifactIndexRecord>*/ artifacts )
+ {
+ List dependencies = new ArrayList();
+
+ for ( Iterator i = artifacts.iterator(); i.hasNext(); )
+ {
+ Dependency dependency = (Dependency) i.next();
+
+ dependencies.add( new DependencyWrapper( dependency ) );
+ }
+
+ return dependencies;
+ }
+
+ public static Collection /*<DependencyWrapper*/ merge( Collection /*<StandardArtifactIndexRecord>*/ artifacts )
+ {
+ Map dependees = new LinkedHashMap();
+
+ for ( Iterator i = artifacts.iterator(); i.hasNext(); )
+ {
+ StandardArtifactIndexRecord record = (StandardArtifactIndexRecord) i.next();
+
+ String key = record.getGroupId() + ":" + record.getArtifactId();
+ if ( dependees.containsKey( key ) )
+ {
+ DependencyWrapper wrapper = (DependencyWrapper) dependees.get( key );
+ wrapper.addVersion( record.getVersion() );
+ }
+ else
+ {
+ DependencyWrapper wrapper = new DependencyWrapper( record );
+
+ dependees.put( key, wrapper );
+ }
+ }
+
+ return dependees.values();
+ }
+
+ public static class DependencyWrapper
+ {
+ private final String groupId;
+
+ private final String artifactId;
+
+ /**
+ * Versions added. We ignore duplicates since you might add those with varying classifiers.
+ */
+ private Set versions = new HashSet();
+
+ private String version;
+
+ private String scope;
+
+ private String classifier;
+
+ public DependencyWrapper( StandardArtifactIndexRecord record )
+ {
+ this.groupId = record.getGroupId();
+
+ this.artifactId = record.getArtifactId();
+
+ addVersion( record.getVersion() );
+ }
+
+ public DependencyWrapper( Dependency dependency )
+ {
+ this.groupId = dependency.getGroupId();
+
+ this.artifactId = dependency.getArtifactId();
+
+ this.scope = dependency.getScope();
+
+ this.classifier = dependency.getClassifier();
+
+ addVersion( dependency.getVersion() );
+ }
+
+ public String getScope()
+ {
+ return scope;
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public void addVersion( String version )
+ {
+ // We use DefaultArtifactVersion to get the correct sorting order later, however it does not have
+ // hashCode properly implemented, so we add it here.
+ // TODO: add these methods to the actual DefaultArtifactVersion and use that.
+ versions.add( new DefaultArtifactVersion( version )
+ {
+ public int hashCode()
+ {
+ int result;
+ result = getBuildNumber();
+ result = 31 * result + getMajorVersion();
+ result = 31 * result + getMinorVersion();
+ result = 31 * result + getIncrementalVersion();
+ result = 31 * result + ( getQualifier() != null ? getQualifier().hashCode() : 0 );
+ return result;
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+
+ DefaultArtifactVersion that = (DefaultArtifactVersion) o;
+
+ if ( getBuildNumber() != that.getBuildNumber() )
+ {
+ return false;
+ }
+ if ( getIncrementalVersion() != that.getIncrementalVersion() )
+ {
+ return false;
+ }
+ if ( getMajorVersion() != that.getMajorVersion() )
+ {
+ return false;
+ }
+ if ( getMinorVersion() != that.getMinorVersion() )
+ {
+ return false;
+ }
+ if ( getQualifier() != null ? !getQualifier().equals( that.getQualifier() )
+ : that.getQualifier() != null )
+ {
+ return false;
+ }
+
+ return true;
+ }
+ } );
+
+ if ( versions.size() == 1 )
+ {
+ this.version = version;
+ }
+ else
+ {
+ this.version = null;
+ }
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public List getVersions()
+ {
+ List versions = new ArrayList( this.versions );
+ Collections.sort( versions );
+ return versions;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.validator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.xwork.validator.ValidationException;
+import com.opensymphony.xwork.validator.ValidatorContext;
+import com.opensymphony.xwork.validator.validators.ValidatorSupport;
+
+/**
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ */
+public class IntervalValidator
+ extends ValidatorSupport
+{
+
+ public void validate( Object obj )
+ throws ValidationException
+ {
+ String snapshotsPolicy = (String) getFieldValue( "snapshotsPolicy", obj );
+ String releasesPolicy = (String) getFieldValue( "releasesPolicy", obj );
+ Integer snapshotsInterval = (Integer) getFieldValue( "snapshotsInterval", obj );
+ Integer releasesInterval = (Integer) getFieldValue( "releasesInterval", obj );
+
+ ValidatorContext ctxt = getValidatorContext();
+
+ if ( !snapshotsPolicy.equals( "interval" ) )
+ {
+ if ( snapshotsInterval.intValue() != 0 )
+ {
+ ctxt.addActionError( "Snapshots Interval must be set to zero." );
+ }
+ }
+
+ if ( !releasesPolicy.equals( "interval" ) )
+ {
+ if ( releasesInterval.intValue() != 0 )
+ {
+ ctxt.addActionError( "Releases Interval must be set to zero." );
+ }
+ }
+
+ if ( ctxt.hasActionErrors() )
+ {
+ return;
+ }
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.web.validator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import com.opensymphony.xwork.validator.ValidationException;
+import com.opensymphony.xwork.validator.ValidatorContext;
+import com.opensymphony.xwork.validator.validators.ValidatorSupport;
+
+/**
+ * Validator for synced repository form. The values to be validated depends on the
+ * selected sync method to be used.
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ */
+public class SyncedRepositoryValidator
+ extends ValidatorSupport
+{
+
+ public void validate( Object obj )
+ throws ValidationException
+ {
+
+ String method = (String) getFieldValue( "method", obj );
+ ValidatorContext ctxt = getValidatorContext();
+
+ if ( method.equals( "rsync" ) )
+ {
+ String rsyncHost = (String) getFieldValue( "rsyncHost", obj );
+ if ( rsyncHost == null || rsyncHost.equals( "" ) )
+ {
+ ctxt.addActionError( "Rsync host is required." );
+ }
+
+ String rsyncDirectory = (String) getFieldValue( "rsyncDirectory", obj );
+ if ( rsyncDirectory == null || rsyncDirectory.equals( "" ) )
+ {
+ ctxt.addActionError( "Rsync directory is required." );
+ }
+
+ String rsyncMethod = (String) getFieldValue( "rsyncMethod", obj );
+ if ( rsyncMethod == null || rsyncMethod.equals( "" ) )
+ {
+ ctxt.addActionError( "Rsync method is required." );
+ }
+ else
+ {
+ if ( !rsyncMethod.equals( "anonymous" ) && !rsyncMethod.equals( "ssh" ) )
+ {
+ ctxt.addActionError( "Invalid rsync method" );
+ }
+ }
+
+ String username = (String) getFieldValue( "username", obj );
+ if ( username == null || username.equals( "" ) )
+ {
+ ctxt.addActionError( "Username is required." );
+ }
+
+ }
+ else if ( method.equals( "svn" ) )
+ {
+ String svnUrl = (String) getFieldValue( "svnUrl", obj );
+ if ( svnUrl == null || svnUrl.equals( "" ) )
+ {
+ ctxt.addActionError( "SVN url is required." );
+ }
+
+ String username = (String) getFieldValue( "username", obj );
+ if ( username == null || username.equals( "" ) )
+ {
+ ctxt.addActionError( "Username is required." );
+ }
+ }
+ else if ( method.equals( "cvs" ) )
+ {
+ String cvsRoot = (String) getFieldValue( "cvsRoot", obj );
+ if ( cvsRoot == null || cvsRoot.equals( "" ) )
+ {
+ ctxt.addActionError( "CVS root is required." );
+ }
+ }
+ else if ( method.equals( "file" ) )
+ {
+ String directory = (String) getFieldValue( "directory", obj );
+ if ( directory == null || directory.equals( "" ) )
+ {
+ ctxt.addActionError( "Directory is required." );
+ }
+ }
+
+ if ( ctxt.hasActionErrors() )
+ {
+ return;
+ }
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<plexus>
+ <components>
+
+ <component>
+ <role>org.codehaus.plexus.registry.Registry</role>
+ <implementation>org.codehaus.plexus.registry.commons.CommonsConfigurationRegistry</implementation>
+ <role-hint>commons-configuration</role-hint>
+ <configuration>
+ <properties>
+ <system/>
+ <jndi prefix="java:comp/env" config-optional="true"/>
+ <xml fileName="${user.home}/.m2/archiva.xml" config-optional="true" config-name="org.apache.maven.archiva.user"
+ config-at="org.apache.maven.archiva" />
+ <xml fileName="${user.home}/.m2/shared.xml" config-optional="true"
+ config-name="org.apache.maven.shared.app.user" config-at="org.apache.maven.shared.app"
+ config-forceCreate="true"/>
+ <properties fileName="${user.home}/.m2/security.properties" config-optional="true"
+ config-at="org.codehaus.plexus.security"/>
+ <properties fileName="${user.home}/.m2/archiva.properties" config-optional="true"
+ config-at="org.codehaus.plexus.security"/>
+ <xml fileName="${appserver.base}/conf/archiva.xml" config-optional="true" config-name="org.apache.maven.archiva.base"
+ config-at="org.apache.maven.archiva"/>
+ <xml fileName="${appserver.base}/conf/shared.xml" config-optional="true"
+ config-name="org.apache.maven.shared.app.base" config-at="org.apache.maven.shared.app"/>
+ <xml fileName="${appserver.base}/conf/common.xml" config-optional="true"/>
+ <properties fileName="${appserver.base}/conf/security.properties" config-optional="true"
+ config-at="org.codehaus.plexus.security"/>
+ <xml fileName="${appserver.home}/conf/archiva.xml" config-optional="true"
+ config-at="org.apache.maven.archiva"/>
+ <xml fileName="${appserver.home}/conf/shared.xml" config-optional="true"
+ config-at="org.apache.maven.shared.app"/>
+ <xml fileName="${appserver.home}/conf/common.xml" config-optional="true"/>
+ <properties fileName="${appserver.home}/conf/security.properties" config-optional="true"
+ config-at="org.codehaus.plexus.security"/>
+ <properties fileName="org/apache/maven/archiva/security.properties" config-at="org.codehaus.plexus.security"/>
+ </properties>
+ </configuration>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.mailsender.MailSender</role>
+ <implementation>org.codehaus.plexus.mailsender.javamail.JndiJavamailMailSender</implementation>
+ <configuration>
+ <jndiSessionName>java:comp/env/mail/Session</jndiSessionName>
+ </configuration>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.webdav.DavServerManager</role>
+ <role-hint>default</role-hint>
+ <implementation>org.codehaus.plexus.webdav.DefaultDavServerManager</implementation>
+ <description>DefaultDavServerManager</description>
+ <configuration>
+ <provider-hint>proxied</provider-hint>
+ </configuration>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.jdo.JdoFactory</role>
+ <role-hint>archiva</role-hint>
+ <implementation>org.codehaus.plexus.jdo.DataSourceConfigurableJdoFactory</implementation>
+ <configuration>
+
+ <connectionFactoryName>java:comp/env/jdbc/archiva</connectionFactoryName>
+ <shutdownConnectionFactoryName>java:comp/env/jdbc/archivaShutdown</shutdownConnectionFactoryName>
+
+ <!-- JPOX and JDO configuration -->
+ <persistenceManagerFactoryClass>org.jpox.PersistenceManagerFactoryImpl</persistenceManagerFactoryClass>
+ <otherProperties>
+ <property>
+ <name>org.jpox.autoCreateSchema</name>
+ <value>true</value>
+ </property>
+ <property>
+ <name>org.jpox.validateTables</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.validateConstraints</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.validateColumns</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.autoStartMechanism</name>
+ <value>None</value>
+ </property>
+ <property>
+ <name>org.jpox.transactionIsolation</name>
+ <value>READ_UNCOMMITTED</value>
+ </property>
+ <property>
+ <name>org.jpox.poid.transactionIsolation</name>
+ <value>READ_UNCOMMITTED</value>
+ </property>
+ <property>
+ <name>org.jpox.rdbms.dateTimezone</name>
+ <value>JDK_DEFAULT_TIMEZONE</value>
+ </property>
+ <!-- NEEDED FOR POSTGRES, But causes problems in other JDBC implementations.
+ <property>
+ <name>org.jpox.identifier.case</name>
+ <value>PreserveCase</value>
+ </property>
+ -->
+ </otherProperties>
+ </configuration>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.jdo.JdoFactory</role>
+ <role-hint>users</role-hint>
+ <implementation>org.codehaus.plexus.jdo.DataSourceConfigurableJdoFactory</implementation>
+ <configuration>
+
+ <connectionFactoryName>java:comp/env/jdbc/users</connectionFactoryName>
+ <shutdownConnectionFactoryName>java:comp/env/jdbc/usersShutdown</shutdownConnectionFactoryName>
+
+ <!-- JPOX and JDO configuration -->
+ <persistenceManagerFactoryClass>org.jpox.PersistenceManagerFactoryImpl</persistenceManagerFactoryClass>
+ <otherProperties>
+ <property>
+ <name>org.jpox.autoCreateSchema</name>
+ <value>true</value>
+ </property>
+ <property>
+ <name>org.jpox.validateTables</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.validateConstraints</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.validateColumns</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.autoStartMechanism</name>
+ <value>None</value>
+ </property>
+ <property>
+ <name>org.jpox.transactionIsolation</name>
+ <value>READ_UNCOMMITTED</value>
+ </property>
+ <property>
+ <name>org.jpox.poid.transactionIsolation</name>
+ <value>READ_UNCOMMITTED</value>
+ </property>
+ <property>
+ <name>org.jpox.rdbms.dateTimezone</name>
+ <value>JDK_DEFAULT_TIMEZONE</value>
+ </property>
+ <!-- NEEDED FOR POSTGRES, But causes problems in other JDBC implementations.
+ <property>
+ <name>org.jpox.identifier.case</name>
+ <value>PreserveCase</value>
+ </property>
+ -->
+ </otherProperties>
+ </configuration>
+ </component>
+
+ <!--
+ | Logger manager
+ -->
+ <component>
+ <role>org.codehaus.plexus.logging.LoggerManager</role>
+ <implementation>org.codehaus.plexus.logging.slf4j.Slf4jLoggerManager</implementation>
+ <lifecycle-handler>basic</lifecycle-handler>
+ </component>
+ </components>
+
+ <load-on-start>
+ <component>
+ <role>org.apache.maven.archiva.scheduler.RepositoryTaskScheduler</role>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
+ <role-hint>data-refresh</role-hint>
+ </component>
+ </load-on-start>
+
+ <lifecycle-handler-manager implementation="org.codehaus.plexus.lifecycle.DefaultLifecycleHandlerManager">
+ <default-lifecycle-handler-id>plexus</default-lifecycle-handler-id>
+ <lifecycle-handlers>
+ <lifecycle-handler implementation="org.codehaus.plexus.personality.plexus.PlexusLifecycleHandler">
+ <id>plexus</id>
+ <name>Plexus Lifecycle Handler</name>
+ <begin-segment>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.LogEnablePhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.CompositionPhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.ContextualizePhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.AutoConfigurePhase"/>
+ <phase implementation="org.codehaus.plexus.registry.RegistryConfigurePhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.ServiceablePhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializePhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.StartPhase"/>
+ </begin-segment>
+ <suspend-segment>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.SuspendPhase"/>
+ </suspend-segment>
+ <resume-segment>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.ResumePhase"/>
+ </resume-segment>
+ <end-segment>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.StopPhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.DisposePhase"/>
+ <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.LogDisablePhase"/>
+ </end-segment>
+ </lifecycle-handler>
+ </lifecycle-handlers>
+ </lifecycle-handler-manager>
+</plexus>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
+<taglib>
+
+ <tlib-version>2.2.3</tlib-version>
+ <jsp-version>1.2</jsp-version>
+ <short-name>Archiva Taglib</short-name>
+
+ <uri>http://maven.apache.org/archiva</uri>
+
+ <display-name>Archiva Taglib</display-name>
+ <description><![CDATA[Archiva JSP Taglib]]></description>
+
+ <tag>
+
+ <name>groupIdLink</name>
+ <tag-class>org.apache.maven.archiva.web.tags.GroupIdLinkTag</tag-class>
+ <body-content>empty</body-content>
+ <description><![CDATA[Render a groupId as a set of Links]]></description>
+
+ <attribute>
+ <name>var</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+
+ <description><![CDATA[The GroupID String]]></description>
+ </attribute>
+
+ <attribute>
+ <name>includeTop</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+
+ <description><![CDATA[Boolean indicating if 'top' link should be created or not.]]></description>
+ </attribute>
+
+ </tag>
+
+ <tag>
+
+ <name>downloadArtifact</name>
+ <tag-class>org.apache.maven.archiva.web.tags.DownloadArtifactTag</tag-class>
+ <body-content>empty</body-content>
+ <description><![CDATA[Render a a set of download links for an artifact]]></description>
+
+ <attribute>
+ <name>groupId</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+
+ <description><![CDATA[The GroupID String]]></description>
+ </attribute>
+
+ <attribute>
+ <name>artifactId</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+
+ <description><![CDATA[The ArtifactID String]]></description>
+ </attribute>
+
+ <attribute>
+ <name>version</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+
+ <description><![CDATA[The Version String]]></description>
+ </attribute>
+
+ <attribute>
+ <name>mini</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+
+ <description><![CDATA[Boolean indicating if the download link is to be generated in mini format instead.]]></description>
+ </attribute>
+
+ </tag>
+
+
+</taglib>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+ <appender name="rolling" class="org.apache.log4j.DailyRollingFileAppender">
+ <param name="file" value="${appserver.base}/logs/archiva.log" />
+ <param name="append" value="true" />
+ <param name="datePattern" value="'.'yyyy-MM-dd" />
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-4r [%t] %-5p %c %x - %m%n"/>
+ </layout>
+ </appender>
+
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d [%t] %-5p %-30c{1} - %m%n"/>
+ </layout>
+ </appender>
+
+ <!-- Help identify bugs during testing -->
+ <logger name="org.apache.maven">
+ <level value="info"/>
+ </logger>
+
+ <logger name="org.codehaus.plexus.security">
+ <level value="info"/>
+ </logger>
+
+ <!-- squelch noisy objects (for now) -->
+ <logger name="org.codehaus.plexus.mailsender.MailSender">
+ <level value="info"/>
+ </logger>
+
+ <logger name="org.quartz">
+ <level value="info"/>
+ </logger>
+
+ <logger name="org.apache.jasper">
+ <level value="info"/>
+ </logger>
+
+ <logger name="com.opensymphony.xwork">
+ <level value="info"/>
+ </logger>
+
+ <logger name="com.opensymphony.webwork">
+ <level value="info"/>
+ </logger>
+
+ <logger name="org.codehaus.plexus.PlexusContainer">
+ <level value="info"/>
+ </logger>
+
+ <logger name="JPOX">
+ <level value="warn"/>
+ </logger>
+
+ <logger name="JPOX.MetaData">
+ <level value="error"/>
+ </logger>
+
+ <logger name="JPOX.RDBMS.SQL">
+ <level value="error"/>
+ </logger>
+
+ <logger name="SQL">
+ <level value="error"/>
+ </logger>
+
+ <logger name="freemarker">
+ <level value="warn"/>
+ </logger>
+
+ <logger name="org.codehaus.plexus.component.manager.ClassicSingletonComponentManager">
+ <level value="error"/>
+ </logger>
+
+ <root>
+ <priority value ="warn" />
+ <appender-ref ref="console" />
+ <appender-ref ref="rolling" />
+ </root>
+
+</log4j:configuration>
--- /dev/null
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+# --------------------------------------------------------------------
+# Email Settings
+
+# The subject line for the email message.
+email.validation.subject=Welcome to Maven Archiva
+
+# Feedback page
+email.feedback.path=http://maven.apache.org/archiva/mail-lists.html
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="md5">
+ <field-validator type="requiredstring">
+ <message>
+ You must select a file, or enter the checksum. If the file was given and you receive this message,
+ there may have been an error generating the checksum.
+ </message>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="q">
+ <field-validator type="requiredstring">
+ <message>You must enter some search terms.</message>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="indexPath">
+ <field-validator type="requiredstring">
+ <message>You must enter the index directory.</message>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
--- /dev/null
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="companyPom.groupId">
+ <field-validator type="requiredstring">
+ <message key="appearance.groupId.required"/>
+ </field-validator>
+ </field>
+ <field name="companyPom.artifactId">
+ <field-validator type="requiredstring">
+ <message key="appearance.artifactId.required"/>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
--- /dev/null
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+appearance.groupId.required = You must define a group identifier.
+appearance.artifactId.required = You must define an artifact identifier.
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="id">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository identifier.</message>
+ </field-validator>
+ <!--field-validator type="regex">
+ <param name="expression"><![CDATA[([A-Z][a-z][0-9])]]></param>
+ <message>Id must not have special characters.</message>
+ </field-validator-->
+ </field>
+ <field name="name">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository name.</message>
+ </field-validator>
+ </field>
+
+ <field name="url">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository URL.</message>
+ </field-validator>
+ </field>
+ <field name="snapshotsInterval">
+ <field-validator type="regex">
+ <param name="expression"><![CDATA[([0-9])]]></param>
+ <message>The value must be numeric</message>
+ </field-validator>
+ </field>
+ <field name="releasesInterval">
+ <field-validator type="regex">
+ <param name="expression"><![CDATA[([0-9])]]></param>
+ <message>The value must be numeric</message>
+ </field-validator>
+ </field>
+
+ <!-- TODO: is the validation correct? -->
+ <validator type="interval">
+ <message/>
+ </validator>
+
+ <field name="layout">
+ <field-validator type="required">
+ <message>Repository type is required.</message>
+ </field-validator>
+ <field-validator type="fieldexpression">
+ <param name="expression">layout in {"legacy", "default"}</param>
+ <message>Invalid repository type.</message>
+ </field-validator>
+ </field>
+ <field name="snapshotsPolicy">
+ <field-validator type="fieldexpression">
+ <param name="expression">snapshotsPolicy in { "disabled", "daily", "hourly", "never", "interval" }</param>
+ <message>Invalid snapshot policy.</message>
+ </field-validator>
+ </field>
+ <field name="releasesPolicy">
+ <field-validator type="fieldexpression">
+ <param name="expression">releasesPolicy in { "disabled", "daily", "hourly", "never", "interval" }</param>
+ <message>Invalid releases policy.</message>
+ </field-validator>
+ </field>
+
+ <field name="managedRepository">
+ <field-validator type="requiredstring">
+ <message>A managed repository must be selected.</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="id">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository identifier.</message>
+ </field-validator>
+ </field>
+ <field name="urlName">
+ <field-validator type="requiredstring">
+ <message>You must enter the url name.</message>
+ </field-validator>
+ </field>
+ <field name="name">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository name.</message>
+ </field-validator>
+ </field>
+ <field name="directory">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository directory.</message>
+ </field-validator>
+ </field>
+ <field name="layout">
+ <field-validator type="fieldexpression">
+ <param name="expression">layout in {"legacy", "default"}</param>
+ <message>Invalid repository type.</message>
+ </field-validator>
+ </field>
+</validators>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="id">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository identifier.</message>
+ </field-validator>
+ </field>
+ <field name="name">
+ <field-validator type="requiredstring">
+ <message>You must enter the repository name.</message>
+ </field-validator>
+ </field>
+ <field name="layout">
+ <field-validator type="requiredstring">
+ <message>Select repository type.</message>
+ </field-validator>
+ <field-validator type="fieldexpression">
+ <param name="expression">layout in {"legacy", "default"}</param>
+ <message>Invalid repository type.</message>
+ </field-validator>
+ </field>
+ <field name="managedRepository">
+ <field-validator type="requiredstring">
+ <message>A managed repository must be selected.</message>
+ </field-validator>
+ </field>
+
+ <validator type="syncedrepo">
+ <message/>
+ </validator>
+
+</validators>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+
+<validators>
+ <field name="method">
+ <field-validator type="requiredstring">
+ <message>You must enter the synchronization method.</message>
+ </field-validator>
+ <field-validator type="fieldexpression">
+ <param name="expression">method in { "rsync", "cvs", "svn", "file" }</param>
+ <message>Invalid method.</message>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<validators>
+ <validator name="required" class="com.opensymphony.xwork.validator.validators.RequiredFieldValidator"/>
+ <validator name="requiredstring" class="com.opensymphony.xwork.validator.validators.RequiredStringValidator"/>
+ <validator name="int" class="com.opensymphony.xwork.validator.validators.IntRangeFieldValidator"/>
+ <validator name="double" class="com.opensymphony.xwork.validator.validators.DoubleRangeFieldValidator"/>
+ <validator name="date" class="com.opensymphony.xwork.validator.validators.DateRangeFieldValidator"/>
+ <validator name="expression" class="com.opensymphony.xwork.validator.validators.ExpressionValidator"/>
+ <validator name="fieldexpression" class="com.opensymphony.xwork.validator.validators.FieldExpressionValidator"/>
+ <validator name="email" class="com.opensymphony.xwork.validator.validators.EmailValidator"/>
+ <validator name="url" class="com.opensymphony.xwork.validator.validators.URLValidator"/>
+ <validator name="visitor" class="com.opensymphony.xwork.validator.validators.VisitorFieldValidator"/>
+ <validator name="conversion" class="com.opensymphony.xwork.validator.validators.ConversionErrorFieldValidator"/>
+ <validator name="stringlength" class="com.opensymphony.xwork.validator.validators.StringLengthFieldValidator"/>
+ <validator name="regex" class="com.opensymphony.xwork.validator.validators.RegexFieldValidator"/>
+ <validator name="interval" class="org.apache.maven.archiva.web.validator.IntervalValidator"/>
+ <validator name="syncedrepo" class="org.apache.maven.archiva.web.validator.SyncedRepositoryValidator"/>
+</validators>
+
--- /dev/null
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+# define our own action mapper here
+webwork.mapper.class = org.apache.maven.archiva.web.mapper.RepositoryActionMapper
+webwork.objectFactory = org.codehaus.plexus.xwork.PlexusObjectFactory
+webwork.url.includeParams = none
+
+# TODO: package up a theme and share with Continuum. Should contain everything from xhtml, and set templateDir to WEB-INF/themes
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1//EN"
+ "http://www.opensymphony.com/xwork/xwork-1.1.dtd">
+
+<xwork>
+ <!-- TODO: better error handling for exceptions needed! -->
+ <include file="webwork-default.xml"/>
+
+ <!-- Include plexus-security xwork configurations. -->
+ <include file="xwork-security.xml"/>
+
+ <package name="base" extends="webwork-default">
+ <interceptors>
+ <interceptor name="configuration" class="configurationInterceptor"/>
+ <interceptor name="pssForceAdminUser" class="pssForceAdminUserInterceptor"/>
+ <interceptor name="pssSecureActions" class="pssSecureActionInterceptor"/>
+ <interceptor name="pssAutoLogin" class="pssAutoLoginInterceptor"/>
+ <interceptor name="pssEnvironmentChecker" class="pssEnvironmentCheckInterceptor"/>
+ <interceptor name="pssPolicyEnforcement" class="pssPolicyEnforcementInterceptor"/>
+
+ <interceptor-stack name="unconfiguredStack">
+ <interceptor-ref name="defaultStack"/>
+ <interceptor-ref name="pssEnvironmentChecker"/>
+ <interceptor-ref name="pssForceAdminUser"/>
+ <interceptor-ref name="pssAutoLogin"/>
+ <interceptor-ref name="pssPolicyEnforcement"/>
+ <interceptor-ref name="pssSecureActions"/>
+ </interceptor-stack>
+
+ <interceptor-stack name="configuredStack">
+ <interceptor-ref name="defaultStack"/>
+ <interceptor-ref name="pssEnvironmentChecker"/>
+ <interceptor-ref name="pssForceAdminUser"/>
+ <interceptor-ref name="pssAutoLogin"/>
+ <interceptor-ref name="pssPolicyEnforcement"/>
+ <interceptor-ref name="pssSecureActions"/>
+ <interceptor-ref name="configuration"/>
+ </interceptor-stack>
+
+ <interceptor-stack name="configuredPrepareParamsStack">
+ <interceptor-ref name="paramsPrepareParamsStack"/>
+ <interceptor-ref name="configuredStack"/>
+ </interceptor-stack>
+ </interceptors>
+
+ <!-- Default interceptor stack. -->
+ <default-interceptor-ref name="configuredStack"/>
+
+ <global-results>
+ <!-- TODO: want an extra message on the configure page when this first happens! -->
+ <!-- TODO: can we send them back to the original location afterwards? -->
+ <result name="config-needed" type="redirect-action">
+ <param name="namespace">/admin</param>
+ <param name="actionName">configure</param>
+ </result>
+
+ <!-- This redirect is triggered by the configuration interceptor -->
+ <result name="config-repository-needed" type="redirect-action">
+ <param name="namespace">/admin</param>
+ <param name="actionName">addRepository</param>
+ <param name="method">input</param>
+ </result>
+
+ <!-- The following security-* result names arrive from the plexus-security package -->
+ <result name="security-login-success" type="redirect-action">index</result>
+ <result name="security-login-cancel" type="redirect-action">index</result>
+ <result name="security-login-locked" type="redirect-action">
+ <param name="infoMessage">Account Locked</param>
+ <param name="actionName">index</param>
+ </result>
+ <result name="security-logout" type="redirect-action">index</result>
+ <result name="requires-authentication" type="redirect-action">
+ <param name="actionName">login</param>
+ <param name="namespace">/security</param>
+ </result>
+ <result name="requires-authorization" type="redirect-action">
+ <param name="actionName">login</param>
+ <param name="namespace">/security</param>
+ </result>
+ <result name="security-register-success" type="redirect-action">
+ <param name="actionName">login</param>
+ <param name="namespace">/security</param>
+ </result>
+ <result name="security-register-cancel" type="redirect-action">
+ <param name="actionName">login</param>
+ <param name="namespace">/security</param>
+ </result>
+ <result name="security-account-success" type="redirect-action">index</result>
+ <result name="security-account-cancel" type="redirect-action">
+ <param name="actionName">login</param>
+ <param name="namespace">/security</param>
+ </result>
+ <result name="security-admin-user-created" type="redirect-action">
+ <param name="actionName">login</param>
+ <param name="namespace">/security</param>
+ </result>
+ <result name="security-admin-user-needed" type="redirect-action">
+ <param name="actionName">addadmin</param>
+ <param name="namespace">/security</param>
+ </result>
+ <result name="security-must-change-password" type="redirect-action">
+ <param name="actionName">password</param>
+ <param name="namespace">/security</param>
+ </result>
+
+ <!-- Generic Catchall for those action configurations that forget to
+ include a result for 'error' -->
+ <result name="error">/WEB-INF/jsp/generalError.jsp</result>
+ </global-results>
+ </package>
+
+ <!-- Configuration for the default package. -->
+ <package name="default" extends="base" namespace="/">
+
+ <!-- This is the redirection facility for plexus-security,
+ allowing plexus-security to call out from its own set of actions
+ into the application webapp, using global result names. -->
+ <action name="pssRedirect" class="pss-redirect" method="redirect">
+ <result type="redirect-action">browse</result>
+ </action>
+
+ <action name="index" class="searchAction" method="input">
+ <result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
+ </action>
+
+ <action name="quickSearch" class="searchAction" method="quickSearch">
+ <result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
+ <result>/WEB-INF/jsp/results.jsp</result>
+ <result name="error">/WEB-INF/jsp/quickSearch.jsp</result>
+ </action>
+
+ <action name="findArtifact" class="searchAction" method="input">
+ <result name="input">/WEB-INF/jsp/findArtifact.jsp</result>
+ </action>
+
+ <action name="checksumSearch" class="searchAction" method="findArtifact">
+ <result name="input">/WEB-INF/jsp/findArtifact.jsp</result>
+ <result name="results">/WEB-INF/jsp/results.jsp</result>
+ <result name="error">/WEB-INF/jsp/findArtifact.jsp</result>
+ <result name="artifact" type="redirect">
+ /browse/${searchResults[0].groupId}/${searchResults[0].artifactId}/${searchResults[0].version}
+ </result>
+ </action>
+
+ <action name="browse" class="browseAction" method="browse">
+ <result>/WEB-INF/jsp/browse.jsp</result>
+ </action>
+
+ <action name="browseGroup" class="browseAction" method="browseGroup">
+ <result>/WEB-INF/jsp/browseGroup.jsp</result>
+ </action>
+
+ <action name="browseArtifact" class="browseAction" method="browseArtifact">
+ <result>/WEB-INF/jsp/browseArtifact.jsp</result>
+ </action>
+
+ <action name="showArtifact" class="showArtifactAction" method="artifact">
+ <result>/WEB-INF/jsp/showArtifact.jsp</result>
+ </action>
+
+ <action name="showArtifactMailingLists" class="showArtifactAction" method="mailingLists">
+ <result>/WEB-INF/jsp/showArtifact.jsp</result>
+ </action>
+
+ <action name="showArtifactReports" class="showArtifactAction" method="reports">
+ <result>/WEB-INF/jsp/showArtifact.jsp</result>
+ </action>
+
+ <action name="showArtifactDependencies" class="showArtifactAction" method="dependencies">
+ <result>/WEB-INF/jsp/showArtifact.jsp</result>
+ </action>
+
+ <action name="showArtifactDependees" class="showArtifactAction" method="dependees">
+ <result>/WEB-INF/jsp/showArtifact.jsp</result>
+ </action>
+
+ <action name="showArtifactDependencyTree" class="showArtifactAction" method="dependencyTree">
+ <result>/WEB-INF/jsp/showArtifact.jsp</result>
+ </action>
+
+ </package>
+
+ <package name="components" namespace="/components" extends="webwork-default">
+ <default-interceptor-ref name="basicStack"/>
+ <action name="companyInfo" class="companyInfo">
+ <result>/WEB-INF/jsp/components/companyLogo.jsp</result>
+ </action>
+ </package>
+
+ <!-- Configuration for the admin package. -->
+ <package name="admin" namespace="/admin" extends="base">
+
+ <action name="index" class="configureAction" method="input">
+ <result name="input">/WEB-INF/jsp/admin/index.jsp</result>
+ </action>
+
+ <action name="managedRepositories" class="configureAction" method="input">
+ <result name="input">/WEB-INF/jsp/admin/managedRepositories.jsp</result>
+ </action>
+
+ <action name="addRepository" class="configureRepositoryAction" method="add">
+ <result name="input">/WEB-INF/jsp/admin/addRepository.jsp</result>
+ <result type="redirect-action">managedRepositories</result>
+ <interceptor-ref name="unconfiguredStack"/>
+ </action>
+
+ <action name="editRepository" class="configureRepositoryAction" method="edit">
+ <result name="input">/WEB-INF/jsp/admin/editRepository.jsp</result>
+ <result type="redirect-action">managedRepositories</result>
+ <interceptor-ref name="configuredPrepareParamsStack"/>
+ </action>
+
+ <action name="deleteRepository" class="deleteRepositoryAction">
+ <result name="input">/WEB-INF/jsp/admin/deleteRepository.jsp</result>
+ <result type="redirect-action">managedRepositories</result>
+ </action>
+
+ <action name="proxiedRepositories" class="configureAction" method="input">
+ <result name="input">/WEB-INF/jsp/admin/proxiedRepositories.jsp</result>
+ </action>
+
+ <action name="addProxiedRepository" class="configureProxiedRepositoryAction" method="add">
+ <result name="input">/WEB-INF/jsp/admin/addProxiedRepository.jsp</result>
+ <result type="redirect-action">proxiedRepositories</result>
+ </action>
+
+ <action name="editProxiedRepository" class="configureProxiedRepositoryAction" method="edit">
+ <result name="input">/WEB-INF/jsp/admin/editProxiedRepository.jsp</result>
+ <result type="redirect-action">proxiedRepositories</result>
+ <interceptor-ref name="configuredPrepareParamsStack"/>
+ </action>
+
+ <action name="deleteProxiedRepository" class="deleteProxiedRepositoryAction">
+ <result name="input">/WEB-INF/jsp/admin/deleteProxiedRepository.jsp</result>
+ <result type="redirect-action">proxiedRepositories</result>
+ </action>
+
+ <action name="syncedRepositories" class="configureAction" method="input">
+ <result name="input">/WEB-INF/jsp/admin/syncedRepositories.jsp</result>
+ </action>
+
+ <action name="addSyncedRepository" class="configureSyncedRepositoryAction">
+ <result name="input">/WEB-INF/jsp/admin/selectSyncedRepository.jsp</result>
+ <result type="chain">
+ <param name="actionName">addSelectedSyncedRepository</param>
+ <param name="method">input</param>
+ </result>
+ </action>
+
+ <action name="addSelectedSyncedRepository" class="configureSyncedRepositoryAction" method="add">
+ <result name="input">/WEB-INF/jsp/admin/addSyncedRepository.jsp</result>
+ <result type="redirect-action">syncedRepositories</result>
+ </action>
+
+ <action name="editSyncedRepository" class="configureSyncedRepositoryAction" method="edit">
+ <result name="input">/WEB-INF/jsp/admin/editSyncedRepository.jsp</result>
+ <result type="redirect-action">syncedRepositories</result>
+ <interceptor-ref name="configuredPrepareParamsStack"/>
+ </action>
+
+ <action name="deleteSyncedRepository" class="deleteSyncedRepositoryAction">
+ <result name="input">/WEB-INF/jsp/admin/deleteSyncedRepository.jsp</result>
+ <result type="redirect-action">syncedRepositories</result>
+ </action>
+
+ <action name="configure" class="configureAction" method="input">
+ <result name="input">/WEB-INF/jsp/admin/configure.jsp</result>
+ <interceptor-ref name="unconfiguredStack"/>
+ </action>
+
+ <action name="saveConfiguration" class="configureAction">
+ <result name="input">/WEB-INF/jsp/admin/configure.jsp</result>
+ <result>/WEB-INF/jsp/admin/index.jsp</result>
+ <interceptor-ref name="unconfiguredStack"/>
+ </action>
+
+ <action name="runIndexer" class="runRepositoryTaskAction" method="runRefresh">
+ <result type="redirect-action">index</result>
+ </action>
+
+ <action name="reports" class="reportsAction">
+ <result>/WEB-INF/jsp/reports/reports.jsp</result>
+ </action>
+
+ <action name="runReport" class="reportsAction" method="runReport">
+ <interceptor-ref name="configuredStack"/>
+ <interceptor-ref name="execAndWait"/>
+ <result name="wait" type="redirect">/admin/reports.action?reportGroup=${reportGroup}&repositoryId=${repositoryId}&filter=${filter}</result>
+ <result name="success" type="redirect">/admin/reports.action?reportGroup=${reportGroup}&repositoryId=${repositoryId}&filter=${filter}</result>
+ </action>
+
+ <action name="configureAppearance" class="configureAppearance" method="input">
+ <result name="input">/WEB-INF/jsp/admin/appearance.jsp</result>
+ </action>
+
+ <action name="editAppearance" class="configureAppearance" method="input">
+ <result name="input">/WEB-INF/jsp/admin/editAppearance.jsp</result>
+ </action>
+
+ <action name="saveAppearance" class="configureAppearance">
+ <result name="input">/WEB-INF/jsp/admin/editAppearance.jsp</result>
+ <result type="redirect-action">
+ <param name="actionName">configureAppearance</param>
+ <param name="namespace">/admin</param>
+ </result>
+ </action>
+
+ <action name="editCompanyPom" class="editPom" method="input">
+ <result name="input">/WEB-INF/jsp/admin/editPom.jsp</result>
+ </action>
+
+ <action name="saveCompanyPom" class="editPom">
+ <result name="input">/WEB-INF/jsp/admin/editPom.jsp</result>
+ <result type="redirect-action">
+ <param name="actionName">configureAppearance</param>
+ <param name="namespace">/admin</param>
+ </result>
+ </action>
+ </package>
+</xwork>
+
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<decorators defaultdir="/WEB-INF/jsp/decorators">
+ <excludes>
+ <pattern>/repository/*</pattern>
+ <pattern>/components/*</pattern>
+ </excludes>
+
+ <decorator name="default" page="default.jsp">
+ <pattern>/*</pattern>
+ </decorator>
+</decorators>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Add Proxied Repository</h2>
+
+ <%@ include file="errorMessages.jsp" %>
+
+ <ww:actionmessage/>
+ <ww:form method="post" action="addProxiedRepository" namespace="/admin" validate="true">
+ <ww:textfield name="id" label="Identifier" size="10"/>
+ <%@ include file="/WEB-INF/jsp/admin/include/proxiedRepositoryForm.jspf" %>
+
+ <ww:submit value="Add Repository"/>
+ </ww:form>
+
+ <script type="text/javascript">
+ document.getElementById("addProxiedRepository_id").focus();
+ </script>
+
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Add Managed Repository</h2>
+
+ <ww:actionmessage/>
+ <ww:form method="post" action="addRepository" namespace="/admin" validate="true">
+ <ww:textfield name="id" label="Identifier" size="10" required="true"/>
+ <%@ include file="/WEB-INF/jsp/admin/include/managedRepositoryForm.jspf" %>
+ <ww:checkbox name="indexed" fieldValue="true" value="true" label="Indexed"/>
+ <ww:submit value="Add Repository"/>
+ </ww:form>
+
+ <script type="text/javascript">
+ document.getElementById("addRepository_id").focus();
+ </script>
+
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Add Synced Repository</h2>
+
+ <%@ include file="errorMessages.jsp" %>
+
+ <ww:actionmessage/>
+ <ww:form method="post" action="addSelectedSyncedRepository" namespace="/admin" validate="true">
+ <ww:textfield name="id" label="Identifier" size="10" required="true"/>
+ <%@ include file="/WEB-INF/jsp/admin/include/syncedRepositoryForm.jspf" %>
+
+ <ww:submit value="Add Repository"/>
+ </ww:form>
+
+ <script type="text/javascript">
+ document.getElementById("addSelectedSyncedRepository_id").focus();
+ </script>
+
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<html>
+<head>
+ <title>Configure Appearance</title>
+ <ww:head/>
+</head>
+
+<body>
+<h1>Appearance</h1>
+
+<div style="float: right">
+ <a href="<ww:url action='editAppearance' />">Edit</a>
+</div>
+<h2>Company Details</h2>
+
+<p>
+ The logo in the top right of the screen is controlled by your selected 'company POM'.
+</p>
+
+<ww:set name="companyPom" value="companyPom"/>
+
+<c:if test="${empty(companyPom.groupId) || empty(companyPom.artifactId)}">
+ <p>
+ You have not yet specified a company POM. <a href="<ww:url action='editAppearance' />">Select a Company POM</a>
+ </p>
+</c:if>
+
+<c:if test="${!empty(companyPom.groupId) && !empty(companyPom.artifactId)}">
+ <p>
+ Your selected company POM is below. If you would like to change the organization name, url or logo, you can
+ <a href="<ww:url action='editCompanyPom'/>">edit the POM</a>.
+ </p>
+
+ <ww:set name="companyModel" value="companyModel"/>
+ <table>
+ <ww:label name="companyPom.groupId" label="Group ID"/>
+ <ww:label name="companyPom.artifactId" label="Artifact ID"/>
+ <c:if test="${companyModel != null}">
+ <ww:label name="companyModel.version" label="Version"/>
+ </c:if>
+ </table>
+
+ <div style="float: right">
+ <a href="<ww:url action='editCompanyPom' />">Edit Company POM</a>
+ </div>
+ <h3>POM Information</h3>
+
+ <c:choose>
+ <c:when test="${companyModel != null}">
+ <table>
+ <tr>
+ <th>Name</th>
+ <td>${companyModel.organization.name}</td>
+ </tr>
+ <tr>
+ <th>URL</th>
+ <td><a href="${companyModel.organization.url}">
+ <code>${companyModel.organization.url}</code>
+ </a></td>
+ </tr>
+ <tr>
+ <th>Logo URL</th>
+ <td>
+ <code>${companyModel.properties['organization.logo']}</code>
+ </td>
+ </tr>
+ </table>
+ </c:when>
+ <c:otherwise>
+ Company POM '${companyPom.groupId}:${companyPom.artifactId}' doesn't exist.
+ <a href="<ww:url action='editCompanyPom' />">Create company POM</a>
+ </c:otherwise>
+ </c:choose>
+</c:if>
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div class="errors">
+ <ww:actionerror/>
+</div>
+
+<div id="contentArea">
+ <ww:actionmessage/>
+ <ww:form method="post" action="saveConfiguration" namespace="/admin" validate="true">
+ <ww:textfield name="indexPath" label="Index Directory" size="100" required="true"/>
+ <!--ww:textfield name="indexerCronExpression" label="Indexing Schedule"/-->
+
+ <ww:label value="Indexing Schedule" labelposition="top"/>
+ <ww:div>
+ <ww:textfield name="second" label="Second" size="2"/>
+ <ww:textfield name="minute" label="Minute" labelposition="left" size="2"/>
+ <ww:textfield name="hour" label="Hour" size="2"/>
+ <ww:textfield name="dayOfMonth" label="Day Of Month" size="2"/>
+ <ww:textfield name="month" label="Month" size="2"/>
+ <ww:textfield name="dayOfWeek" label="Day Of Week" size="2"/>
+ <ww:textfield name="year" label="Year" size="4"/>
+ </ww:div>
+
+ <ww:hidden name="proxy.protocol" value="http"/>
+ <ww:textfield name="proxy.host" label="HTTP Proxy Host"/>
+ <ww:textfield name="proxy.port" label="HTTP Proxy Port"/>
+ <ww:textfield name="proxy.username" label="HTTP Proxy Username"/>
+ <ww:password name="proxy.password" label="HTTP Proxy Password"/>
+
+ <ww:submit value="Save Configuration"/>
+
+ <ww:div>
+ <ww:label value="Indexing Schedule Keys:" labelposition="top"/>
+ <ww:label value="* = every" labelposition="top"/>
+ <ww:label value="? = any" labelposition="top"/>
+ <ww:label value="- = ranges" labelposition="top"/>
+ <ww:label value="/ = increments" labelposition="top"/>
+ </ww:div>
+ </ww:form>
+
+ <ww:div>
+ <p><i>For valid cron expression values for the Indexing Schedule, see
+ <ww:a href="http://www.opensymphony.com/quartz/api/org/quartz/CronExpression.html">here</ww:a>
+ </i></p>
+ </ww:div>
+
+ <script type="text/javascript">
+ document.getElementById("saveConfiguration_indexPath").focus();
+ </script>
+
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Delete Proxied Repository</h2>
+
+ <blockquote>
+ <strong><span class="statusFailed">WARNING:</span> This operation can not be undone.</strong>
+ </blockquote>
+
+ <ww:form method="post" action="deleteProxiedRepository" namespace="/admin" validate="true">
+ <ww:hidden name="repoId"/>
+ <ww:radio list="#@java.util.LinkedHashMap@{
+ 'delete-contents' : 'Remove the repository and delete its contents from managed repositories',
+ 'delete-entry' : 'Remove the repository from the available list, but leave the contents in the managed repositories',
+ 'unmodified' : 'Leave the repository unmodified'}" name="operation" theme="archiva"/>
+ <ww:submit value="Go"/>
+ </ww:form>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Delete Managed Repository</h2>
+
+ <blockquote>
+ <strong><span class="statusFailed">WARNING:</span> This operation can not be undone.</strong>
+ </blockquote>
+
+ <ww:form method="post" action="deleteRepository" namespace="/admin" validate="true">
+ <ww:hidden name="repoId"/>
+ <ww:radio list="#@java.util.LinkedHashMap@{'delete-contents' : 'Remove the repository and delete its contents from disk',
+ 'delete-entry' : 'Remove the repository from the management list, but leave the contents unmodified',
+ 'unmodified' : 'Leave the repository unmodified'}" name="operation" theme="archiva"/>
+ <ww:submit value="Go"/>
+ </ww:form>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Delete Synced Repository</h2>
+
+ <blockquote>
+ <strong><span class="statusFailed">WARNING:</span> This operation can not be undone.</strong>
+ </blockquote>
+
+ <ww:form method="post" action="deleteSyncedRepository" namespace="/admin" validate="true">
+ <ww:hidden name="repoId"/>
+ <ww:radio list="#@java.util.LinkedHashMap@{
+ 'delete-contents' : 'Remove the repository and delete its contents from managed repositories',
+ 'delete-entry' : 'Remove the repository from the available list, but leave the contents in the managed repositories',
+ 'unmodified' : 'Leave the repository unmodified'}" name="operation" theme="archiva"/>
+ <ww:submit value="Go"/>
+ </ww:form>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<html>
+<head>
+ <title>Configure Appearance</title>
+ <ww:head/>
+</head>
+
+<body>
+<h1>Appearance</h1>
+
+<h2>Company Details</h2>
+
+<p>
+ Enter the details of the company super POM below. If it exists, the organization name, URL and logo will be read
+ from it.
+</p>
+
+<ww:actionmessage/>
+<ww:form method="post" action="saveAppearance" namespace="/admin" validate="true" theme="xhtml">
+ <ww:textfield name="companyPom.groupId" label="Group ID"/>
+ <ww:textfield name="companyPom.artifactId" label="Artifact ID"/>
+ <ww:submit value="Save"/>
+</ww:form>
+</body>
+
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<html>
+<head>
+ <title>Edit Company POM</title>
+ <ww:head/>
+</head>
+
+<body>
+<h1>Company POM</h1>
+
+<ww:actionmessage/>
+<ww:form method="post" action="saveCompanyPom" namespace="/admin" validate="true" theme="xhtml">
+ <ww:label name="companyModel.groupId" label="Group ID"/>
+ <ww:label name="companyModel.artifactId" label="Artifact ID"/>
+ <tr>
+ <td>Version</td>
+ <td>
+ <ww:property value="companyModel.version"/>
+ <i>(The version will automatically be incremented when you save this form)</i>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><h2>Organization</h2></td>
+ </tr>
+ <ww:textfield name="companyModel.organization.name" size="40" label="Name"/>
+ <ww:textfield name="companyModel.organization.url" size="70" label="URL"/>
+ <%-- TODO: how to get it to be a string, not a String[]? --%>
+ <ww:textfield name="companyModel.properties['organization.logo']" size="70" label="Logo URL"/>
+ <ww:submit value="Save"/>
+</ww:form>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Edit Proxied Repository</h2>
+
+ <%@ include file="errorMessages.jsp" %>
+
+ <ww:actionmessage/>
+ <ww:form method="post" action="editProxiedRepository" namespace="/admin" validate="true">
+ <ww:hidden name="id"/>
+ <%@ include file="/WEB-INF/jsp/admin/include/proxiedRepositoryForm.jspf" %>
+ <ww:submit value="Update Repository"/>
+ </ww:form>
+
+ <script type="text/javascript">
+ document.getElementById("editProxiedRepository_name").focus();
+ </script>
+
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Edit Managed Repository</h2>
+
+ <ww:actionmessage/>
+ <ww:form method="post" action="editRepository" namespace="/admin" validate="true">
+ <ww:hidden name="id"/>
+ <%@ include file="/WEB-INF/jsp/admin/include/managedRepositoryForm.jspf" %>
+ <ww:checkbox name="indexed" fieldValue="true" label="Indexed"/>
+ <ww:submit value="Update Repository"/>
+ </ww:form>
+
+ <script type="text/javascript">
+ document.getElementById("editRepository_name").focus();
+ </script>
+
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Edit Synced Repository</h2>
+
+ <%@ include file="errorMessages.jsp" %>
+
+ <ww:actionmessage/>
+ <ww:form method="post" action="editSyncedRepository" namespace="/admin" validate="true">
+ <ww:hidden name="id"/>
+ <%@ include file="/WEB-INF/jsp/admin/include/syncedRepositoryForm.jspf" %>
+
+ <ww:submit value="Update Repository"/>
+ </ww:form>
+
+ <script type="text/javascript">
+ document.getElementById("editSyncedRepository_name").focus();
+ </script>
+
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<p>
+ <ww:if test="hasActionErrors()">
+ <b style="color: red;">Errors:</b>
+ <ww:iterator value="actionErrors">
+ <li style="color: red;">
+ <ww:property/>
+ </li>
+ </ww:iterator>
+ </ww:if>
+</p>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<c:set var="urlbase">${pageContext.request.scheme}://${pageContext.request.serverName}
+ :${pageContext.request.serverPort}${pageContext.request.contextPath}/repository/
+</c:set>
+
+<tr>
+ <td>
+ <ww:label for="urlName" theme="simple">URL Name*:</ww:label>
+ </td>
+ <td>
+ <c:out value="${urlbase}"/>
+ <ww:textfield name="urlName" id="urlName" size="20" theme="simple" required="true"/>
+ </td>
+</tr>
+
+<ww:textfield name="name" label="Name" size="50" required="true"/>
+<ww:textfield name="directory" label="Directory" size="100" required="true"/>
+<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
+ name="layout" label="Type"/>
+<ww:checkbox name="includeSnapshots" fieldValue="true" label="Snapshots Included"/>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<ww:textfield name="name" label="Name" size="50" required="true"/>
+<ww:textfield name="url" label="URL" size="50" required="true"/>
+<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
+ name="layout" label="Type"/>
+<ww:select name="snapshotsPolicy" label="Snapshots" list="#@java.util.LinkedHashMap@{
+ 'disabled' : 'Disabled',
+ 'daily' : 'Enabled, updated daily',
+ 'hourly' : 'Enabled, updated hourly',
+ 'never' : 'Enabled, never updated',
+ 'interval' : 'Enabled, updated on given interval'}"/>
+<ww:textfield label="Snapshot update interval" name="snapshotsInterval" size="4"/>
+<ww:select name="releasesPolicy" label="Releases" list="#@java.util.LinkedHashMap@{
+ 'disabled' : 'Disabled',
+ 'daily' : 'Enabled, updated daily',
+ 'hourly' : 'Enabled, updated hourly',
+ 'never' : 'Enabled, never updated',
+ 'interval' : 'Enabled, updated on given interval'}"/>
+<ww:textfield label="Release update interval" name="releasesInterval" size="4"/>
+<ww:select list="configuration.repositoriesMap" name="managedRepository" label="Proxied through"/>
+<ww:checkbox name="useNetworkProxy" fieldValue="true" label="Use HTTP Proxy"/>
+<ww:checkbox name="cacheFailures" fieldValue="true" label="Cache Failures"/>
+<ww:checkbox name="hardFail" fieldValue="true" label="Fail Whole Group"/>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<ww:hidden name="method"/>
+<ww:textfield name="name" label="Name" size="50"/>
+<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
+ name="layout" label="Type"/>
+<ww:select list="configuration.repositoriesMap" name="managedRepository" label="Synced to"/>
+<ww:textfield name="cronExpression" label="Schedule"/>
+
+<ww:set name="method" value="method"/>
+<c:choose>
+ <c:when test="${method == 'cvs'}">
+ <ww:textfield name="properties['cvsRoot']" label="CVS Root" size="100"/>
+ </c:when>
+ <c:when test="${method == 'svn'}">
+ <ww:textfield name="properties['svnUrl']" label="Subversion URL" size="100"/>
+ <ww:textfield name="properties['username']" label="Subversion Username" size="30"/>
+ </c:when>
+ <c:when test="${method == 'rsync'}">
+ <ww:textfield name="properties['rsyncHost']" label="Rsync Host"/>
+ <ww:textfield name="properties['rsyncDirectory']" label="Rsync Directory" size="100"/>
+ <ww:select name="properties['rsyncMethod']" label="Rsync Method"
+ list="#@java.util.LinkedHashMap@{'rsync' : 'Anonymous', 'ssh' : 'SSH'}"/>
+ <ww:textfield name="properties['username']" label="Rsync Username" size="30"/>
+ </c:when>
+ <c:when test="${method == 'file'}">
+ <ww:textfield name="properties['directory']" label="Directory" size="100"/>
+ </c:when>
+</c:choose>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
+
+<html>
+<head>
+ <title>Administration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Administration</h1>
+
+<div id="contentArea">
+ <div>
+ <div style="float: right">
+ <%-- TODO replace with icons --%>
+ <pss:ifAuthorized permission="archiva-manage-configuration">
+ <a href="<ww:url action="configure" />">Edit Configuration</a>
+ </pss:ifAuthorized>
+ </div>
+ <h2>Configuration</h2>
+ </div>
+
+ <table class="infoTable">
+ <tr>
+ <th>Index Directory</th>
+ <td>
+ <ww:property value="indexPath"/>
+ </td>
+ <td></td>
+ </tr>
+ <tr>
+ <th>Indexing Schedule</th>
+ <td>
+ <ww:property value="indexerCronExpression"/>
+ </td>
+ <%-- TODO: a "delete index and run now" operation should be here too (really clean, remove deletions that didn't get picked up) --%>
+ </tr>
+ <tr>
+ <th>Last Indexing Time</th>
+ <td>
+ <ww:property value="lastIndexingTime"/>
+ </td>
+ <td></td>
+ </tr>
+ </table>
+
+ <table class="infoTable">
+ <tr>
+ <td>
+ <pss:ifAuthorized permission="archiva-run-indexer">
+ <a href="<ww:url action="runIndexer" />">Run Now</a>
+ </pss:ifAuthorized>
+ </td>
+ </tr>
+ </table>
+
+ <ww:set name="proxy" value="proxy"/>
+ <c:if test="${!empty(proxy.host)}">
+ <h3>HTTP Proxy</h3>
+
+ <table class="infoTable">
+ <tr>
+ <th>Host</th>
+ <td>${proxy.host}</td>
+ </tr>
+ <tr>
+ <th>Port</th>
+ <td>${proxy.port}</td>
+ </tr>
+ <tr>
+ <th>Username</th>
+ <td>${proxy.username}</td>
+ </tr>
+ </table>
+ </c:if>
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
+
+<html>
+<head>
+ <title>Administration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Administration</h1>
+
+<div id="contentArea">
+
+<%-- DO NOT REFORMAT THIS LINE --%>
+<c:set var="urlbase">${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/repository/</c:set>
+
+<div>
+ <div style="float: right">
+ <%-- TODO replace with icons --%>
+ <pss:ifAuthorized permission="archiva-manage-configuration">
+ <ww:url id="addRepositoryUrl" action="addRepository" method="input"/>
+ <ww:a href="%{addRepositoryUrl}">Add Repository</ww:a>
+ </pss:ifAuthorized>
+ </div>
+ <h2>Managed Repositories</h2>
+</div>
+
+<ww:set name="repositories" value="repositories"/>
+<c:if test="${empty(repositories)}">
+ <strong>There are no managed repositories configured yet.</strong>
+</c:if>
+<c:forEach items="${repositories}" var="repository" varStatus="i">
+
+ <div>
+ <div style="float: right">
+ <pss:ifAnyAuthorized permissions="archiva-manage-configuration">
+ <ww:url id="editRepositoryUrl" action="editRepository" method="input">
+ <ww:param name="repoId" value="%{'${repository.id}'}"/>
+ </ww:url>
+ <ww:url id="deleteRepositoryUrl" action="deleteRepository" method="input">
+ <ww:param name="repoId" value="%{'${repository.id}'}"/>
+ </ww:url>
+ <%-- TODO replace with icons --%>
+ <ww:a href="%{editRepositoryUrl}">Edit Repository</ww:a>
+ <ww:a href="%{deleteRepositoryUrl}">Delete Repository</ww:a>
+ </pss:ifAnyAuthorized>
+ </div>
+ <h3>${repository.name}</h3>
+ <table class="infoTable">
+ <tr>
+ <th>Identifier</th>
+ <td>
+ <code>${repository.id}</code>
+ </td>
+ </tr>
+ <tr>
+ <th>Directory</th>
+ <td>${repository.directory}</td>
+ </tr>
+ <tr>
+ <th>WebDAV URL</th>
+ <td><a href="${urlbase}${repository.urlName}/">${urlbase}${repository.urlName}/</a></td>
+ </tr>
+ <tr>
+ <th>Type</th>
+ <%-- TODO: can probably just use layout appended to a key prefix in i18n to simplify this --%>
+ <td>
+ <c:choose>
+ <c:when test="${repository.layout == 'default'}">
+ Maven 2.x Repository
+ </c:when>
+ <c:otherwise>
+ Maven 1.x Repository
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ <tr>
+ <th>Snapshots Included</th>
+ <td class="${repository.includeSnapshots ? 'donemark' : 'errormark'} booleanIcon"> ${repository.includeSnapshots}</td>
+ </tr>
+ <tr>
+ <th>Indexed</th>
+ <td class="${repository.indexed ? 'donemark' : 'errormark'} booleanIcon"> ${repository.indexed}</td>
+ </tr>
+ <tr>
+ <th>POM Snippet</th>
+ <td><a href="#" onclick="Effect.toggle('repoPom${repository.id}','slide'); return false;">Show POM Snippet</a><br/>
+ <%-- DO NOT REFORMAT THIS SECTION --%>
+<pre class="pom" style="display: none;" id="repoPom${repository.id}"><code><project>
+ ...
+ <distributionManagement>
+ <${repository.includeSnapshots ? 'snapshotRepository' : 'repository'}>
+ <id>${repository.id}</id>
+ <url>dav:${urlbase}${repository.urlName}</url>
+ <c:if test="${repository.layout != 'default'}">
+ <layout>${repository.layout}</layout>
+ </c:if>
+ </${repository.includeSnapshots ? 'snapshotRepository' : 'repository'}>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <id>${repository.id}</id>
+ <name>${repository.name}</name>
+ <url>${urlbase}${repository.urlName}/</url>
+ <c:if test="${repository.layout != 'default'}">
+ <layout>${repository.layout}</layout>
+ </c:if>
+ <releases>
+ <enabled>${repository.includeSnapshots ? 'false' : 'true'}</enabled>
+ </releases>
+ <snapshots>
+ <enabled>${repository.includeSnapshots ? 'true' : 'false'}</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ ...
+ </project>
+</code></pre>
+ </td>
+ </tr>
+ </table>
+ </div>
+</c:forEach>
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
+
+<html>
+<head>
+ <title>Administration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Administration</h1>
+
+<div id="contentArea">
+ <div>
+
+ <%-- TODO replace with icons --%>
+ <div style="float: right">
+ <pss:ifAuthorized permission="archiva-manage-configuration">
+ <a href="<ww:url action="addProxiedRepository" method="input" />">Add Repository</a>
+ </pss:ifAuthorized>
+ </div>
+
+ <h2>Proxied Repositories</h2>
+ </div>
+
+ <ww:set name="proxiedRepositories" value="proxiedRepositories"/>
+ <c:if test="${empty(proxiedRepositories)}">
+ <strong>There are no proxied repositories configured yet.</strong>
+ </c:if>
+ <c:forEach items="${proxiedRepositories}" var="repository" varStatus="i">
+ <div>
+ <div style="float: right">
+ <%-- TODO replace with icons --%>
+ <pss:ifAuthorized permission="archiva-manage-configuration">
+ <a href="<ww:url action="editProxiedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Edit
+ Repository</a> | <a
+ href="<ww:url action="deleteProxiedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Delete
+ Repository</a>
+ </pss:ifAuthorized>
+ </div>
+ <h3>${repository.name}</h3>
+ <table class="infoTable">
+ <tr>
+ <th>Identifier</th>
+ <td>
+ <code>${repository.id}</code>
+ </td>
+ </tr>
+ <tr>
+ <th>URL</th>
+ <td><a href="${repository.url}">${repository.url}</a></td>
+ </tr>
+ <tr>
+ <th>Type</th>
+ <%-- TODO: can probably just use layout appended to a key prefix in i18n to simplify this --%>
+ <td>
+ <c:choose>
+ <c:when test="${repository.layout == 'default'}">
+ Maven 2.x Repository
+ </c:when>
+ <c:otherwise>
+ Maven 1.x Repository
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ <tr>
+ <th>Snapshots</th>
+ <td>
+ <my:displayUpdatePolicy policy="${repository.snapshotsPolicy}" interval="${repository.snapshotsInterval}"/>
+ </td>
+ </tr>
+ <tr>
+ <th>Releases</th>
+ <td>
+ <my:displayUpdatePolicy policy="${repository.releasesPolicy}" interval="${repository.releasesInterval}"/>
+ </td>
+ </tr>
+ <tr>
+ <th>Proxied through</th>
+ <td>
+ <%-- TODO: this is the hard way! would be nice if there was a ref in the model so it was directly linked --%>
+ ${repositoriesMap[repository.managedRepository].name}
+ (<code>${repositoriesMap[repository.managedRepository].id}</code>)
+ </td>
+ </tr>
+ <tr>
+ <th>Use HTTP Proxy</th>
+ <td class="${repository.useNetworkProxy ? 'donemark' : 'errormark'} booleanIcon"></td>
+ </tr>
+ <tr>
+ <th>Cache Failures</th>
+ <td class="${repository.cacheFailures ? 'donemark' : 'errormark'} booleanIcon"></td>
+ </tr>
+ <tr>
+ <th>Fail Whole Group</th>
+ <td class="${repository.hardFail ? 'donemark' : 'errormark'} booleanIcon"></td>
+ </tr>
+ </table>
+ </div>
+ </c:forEach>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Configuration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Configuration</h1>
+
+<div id="contentArea">
+
+ <h2>Add Synced Repository</h2>
+
+ <ww:actionmessage/>
+ <ww:form method="post" action="addSyncedRepository" namespace="/admin" validate="true">
+ <ww:select list="#@java.util.LinkedHashMap@{
+ 'rsync' : 'Rsync',
+ 'svn' : 'Subversion',
+ 'cvs' : 'CVS',
+ 'file': 'Local File System'}" name="method" label="Method"/>
+
+ <ww:submit value="Continue"/>
+ </ww:form>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<html>
+<head>
+ <title>Administration</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Administration</h1>
+
+<div id="contentArea">
+<div>
+ <%-- TODO replace with icons --%>
+ <div style="float: right">
+ <a href="<ww:url action="addSyncedRepository" method="input" />">Add Repository</a>
+ </div>
+ <h2>Synced Repositories</h2>
+</div>
+
+<ww:set name="syncedRepositories" value="syncedRepositories"/>
+<c:if test="${empty(syncedRepositories)}">
+ <strong>There are no synced repositories configured yet.</strong>
+</c:if>
+<c:forEach items="${syncedRepositories}" var="repository" varStatus="i">
+ <div>
+ <div style="float: right">
+ <%-- TODO replace with icons --%>
+ <a href="<ww:url action="editSyncedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Edit
+ Repository</a> | <a
+ href="<ww:url action="deleteSyncedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Delete
+ Repository</a>
+ </div>
+ <h3>${repository.name}</h3>
+ <table class="infoTable">
+ <tr>
+ <th>Identifier</th>
+ <td>
+ <code>${repository.id}</code>
+ </td>
+ </tr>
+ <tr>
+ <th>Method</th>
+ <td>${repository.method}</td>
+ </tr>
+ <c:choose>
+ <c:when test="${repository.method == 'cvs'}">
+ <tr>
+ <th>CVS Root</th>
+ <td>${repository.properties['cvsRoot']}</td>
+ </tr>
+ </c:when>
+ <c:when test="${repository.method == 'svn'}">
+ <tr>
+ <th>Subversion URL</th>
+ <td>${repository.properties['svnUrl']}</td>
+ </tr>
+ <tr>
+ <th>Subversion Username</th>
+ <td>${repository.properties['username']}</td>
+ </tr>
+ </c:when>
+ <c:when test="${repository.method == 'rsync'}">
+ <tr>
+ <th>Rsync Host</th>
+ <td>${repository.properties['rsyncHost']}</td>
+ </tr>
+ <tr>
+ <th>Rsync Directory</th>
+ <td>${repository.properties['rsyncDirectory']}</td>
+ </tr>
+ <tr>
+ <th>Rsync Method</th>
+ <td>
+ <c:choose>
+ <c:when test="${repository.properties['rsyncMethod'] == 'rsync'}">
+ Anonymous
+ </c:when>
+ <c:when test="${repository.properties['rsyncMethod'] == 'ssh'}">
+ SSH
+ </c:when>
+ </c:choose>
+ </td>
+ </tr>
+ <tr>
+ <th>Username</th>
+ <td>${repository.properties['username']}</td>
+ </tr>
+ </c:when>
+ <c:when test="${repository.method == 'file'}">
+ <tr>
+ <th>Directory</th>
+ <td>${repository.properties['directory']}</td>
+ </tr>
+ </c:when>
+ </c:choose>
+ <tr>
+ <th>Type</th>
+ <%-- TODO: can probably just use layout appended to a key prefix in i18n to simplify this --%>
+ <td>
+ <c:choose>
+ <c:when test="${repository.layout == 'default'}">
+ Maven 2.x Repository
+ </c:when>
+ <c:otherwise>
+ Maven 1.x Repository
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ <tr>
+ <th>Synced to</th>
+ <td>
+ <%-- TODO: this is the hard way! would be nice if there was a ref in the model so it was directly linked --%>
+ ${repositoriesMap[repository.managedRepository].name}
+ (<code>${repositoriesMap[repository.managedRepository].id}</code>)
+ </td>
+ </tr>
+ <tr>
+ <th>Schedule</th>
+ <td>${repository.cronExpression}</td>
+ </tr>
+ </table>
+ </div>
+</c:forEach>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<html>
+<head>
+ <title>Security Alert Page</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<div id="contentArea">
+ <div id="searchBox">
+ <div id="results">
+ You are not authorized for this activity.
+ </div>
+ </div>
+</div>
+
+<div class="clear">
+ <hr/>
+</div>
+
+</body>
+
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
+
+<html>
+<head>
+ <title>Browse Repository</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Browse Repository</h1>
+
+<div id="contentArea">
+ <div id="nameColumn">
+ <h2>Groups</h2>
+ <ul>
+ <ww:set name="groups" value="groups"/>
+ <c:forEach items="${groups}" var="groupId">
+ <c:set var="url">
+ <ww:url action="browseGroup" namespace="/">
+ <ww:param name="groupId" value="%{'${groupId}'}"/>
+ </ww:url>
+ </c:set>
+ <li><a href="${url}">${groupId}/</a></li>
+ </c:forEach>
+ </ul>
+ </div>
+
+
+ <%-- TODO: later, when supported in metadata
+ <div id="categoryColumn">
+ <h2>Category</h2>
+ <table>
+ <tr>
+ <td>
+ <a href="#">Java</a>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="#">Ruby</a>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ <h2>Labels</h2>
+
+ <div id="labels">
+ <p>
+ <a href="#">jdo</a>
+ <a href="#">j2ee</a>
+ <a href="#">maven</a>
+ </p>
+ </div>
+ --%>
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
+
+<html>
+<head>
+ <title>Browse Repository</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Browse Repository</h1>
+
+<div id="contentArea">
+ <div id="nameColumn">
+ <p>
+ <archiva:groupIdLink var="${groupId}" includeTop="true" />
+ <strong>${artifactId}</strong>
+ </p>
+
+ <h2>Versions</h2>
+ <ul>
+ <ww:set name="versions" value="versions"/>
+ <c:forEach items="${versions}" var="version">
+ <c:set var="url">
+ <ww:url action="showArtifact" namespace="/">
+ <ww:param name="groupId" value="%{'${groupId}'}"/>
+ <ww:param name="artifactId" value="%{'${artifactId}'}"/>
+ <ww:param name="version" value="%{'${version}'}"/>
+ </ww:url>
+ </c:set>
+ <li><a href="${url}">${version}/</a></li>
+ </c:forEach>
+ </ul>
+ </div>
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
+
+<html>
+<head>
+ <title>Browse Repository</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Browse Repository</h1>
+
+<div id="contentArea">
+ <div id="nameColumn">
+ <p>
+ <archiva:groupIdLink var="${groupId}" includeTop="true" />
+ </p>
+
+ <ww:set name="groups" value="groups"/>
+ <c:if test="${!empty(groups)}">
+ <h2>Groups</h2>
+ <ul>
+ <c:forEach items="${groups}" var="groupId">
+ <c:set var="url">
+ <ww:url action="browseGroup" namespace="/">
+ <ww:param name="groupId" value="%{'${groupId}'}"/>
+ </ww:url>
+ </c:set>
+ <li><a href="${url}">${groupId}/</a></li>
+ </c:forEach>
+ </ul>
+ </c:if>
+
+ <ww:set name="artifactIds" value="artifactIds"/>
+ <c:if test="${!empty(artifactIds)}">
+ <h2>Artifacts</h2>
+ <ul>
+ <c:forEach items="${artifactIds}" var="artifactId">
+ <c:set var="url">
+ <ww:url action="browseArtifact" namespace="/">
+ <ww:param name="groupId" value="%{'${groupId}'}"/>
+ <ww:param name="artifactId" value="%{'${artifactId}'}"/>
+ </ww:url>
+ </c:set>
+ <li><a href="${url}">${artifactId}/</a></li>
+ </c:forEach>
+ </ul>
+ </c:if>
+ </div>
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib uri="/webwork" prefix="ww" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<ww:set name="companyLogo" value="companyLogo"/>
+<c:if test="${!empty(companyLogo)}">
+ <ww:set name="companyUrl" value="companyUrl"/>
+ <c:choose>
+ <c:when test="${!empty(companyUrl)}">
+ <a href="${companyUrl}">
+ <img src="${companyLogo}" title="${companyName}" border="0" alt=""/>
+ </a>
+ </c:when>
+ <c:otherwise>
+ <img src="${companyLogo}" title="${companyName}" border="0" alt=""/>
+ </c:otherwise>
+ </c:choose>
+</c:if>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
+<%@ taglib uri="/webwork" prefix="ww" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
+<%@ page import="java.util.Calendar" %>
+<html>
+<head>
+ <title>Maven Archiva ::
+ <decorator:title default="Maven Archiva"/>
+ </title>
+
+ <style type="text/css" media="all">
+ @import url( "<c:url value="/css/maven-base.css" />" );
+ @import url( "<c:url value="/css/maven-theme.css" />" );
+ @import url( "<c:url value="/css/pss/table.css" />" );
+ @import url( "<c:url value="/css/site.css" />" );
+ </style>
+ <link rel="stylesheet" href="<c:url value="/css/print.css"/>" type="text/css" media="print"/>
+ <script type="text/javascript" src="<c:url value="/js/scriptaculous/prototype.js"/>"></script>
+ <script type="text/javascript" src="<c:url value="/js/scriptaculous/scriptaculous.js"/>"></script>
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+</head>
+
+<body onload="<decorator:getProperty property="body.onload" />" class="composite">
+<div id="banner">
+ <span id="bannerLeft">
+ <a href="http://maven.apache.org/archiva/">
+ <img src="<c:url value='/images/archiva.png' />" alt="" width="188" height="69"/>
+ </a>
+ </span>
+ <span id="bannerRight">
+ <ww:action namespace="/components" name="companyInfo" executeResult="true"/>
+ </span>
+
+ <div class="clear">
+ <hr/>
+ </div>
+</div>
+
+<div id="breadcrumbs">
+ <div class="xleft">
+ <%@ include file="/WEB-INF/jsp/pss/include/securityLinks.jsp" %>
+ </div>
+
+ <div class="xright">
+ <a href="http://maven.apache.org/archiva">Archiva</a> |
+ <a href="http://maven.apache.org/">Maven</a> |
+ <a href="http://www.apache.org/">Apache</a>
+ </div>
+
+ <div class="clear">
+ <hr/>
+ </div>
+</div>
+
+<div id="leftColumn">
+
+ <div id="navcolumn">
+
+ <h5>Find</h5>
+ <ul>
+ <li class="none">
+ <my:currentWWUrl action="index" namespace="/">Search</my:currentWWUrl>
+ </li>
+
+ <li class="none">
+ <my:currentWWUrl action="findArtifact" namespace="/">Find Artifact</my:currentWWUrl>
+ </li>
+
+ <li class="none">
+ <my:currentWWUrl action="browse" namespace="/">Browse</my:currentWWUrl>
+ </li>
+ </ul>
+
+ <pss:ifAnyAuthorized permissions="archiva-manage-users,archiva-access-reports,archiva-manage-configuration">
+ <h5>Manage</h5>
+ <ul>
+ <pss:ifAuthorized permission="archiva-access-reports">
+ <li class="none">
+ <my:currentWWUrl action="reports" namespace="/admin">Reports</my:currentWWUrl>
+ </li>
+ </pss:ifAuthorized>
+ <%-- TODO
+ <li class="none">
+ <a href="#">Synchronisation</a>
+ </li>
+ --%>
+ <pss:ifAuthorized permission="archiva-manage-users">
+ <li class="none">
+ <my:currentWWUrl action="userlist" namespace="/security">User Management</my:currentWWUrl>
+ </li>
+ </pss:ifAuthorized>
+ <pss:ifAuthorized permission="archiva-manage-configuration">
+ <li class="none">
+ <my:currentWWUrl action="configureAppearance" namespace="/admin">Appearance</my:currentWWUrl>
+ </li>
+ </pss:ifAuthorized>
+ </ul>
+ </pss:ifAnyAuthorized>
+
+ <pss:ifAuthorized permission="archiva-manage-configuration">
+ <h5>Administration</h5>
+ <ul>
+ <li class="none">
+ <my:currentWWUrl action="index" namespace="/admin">Settings</my:currentWWUrl>
+ </li>
+ <li class="none">
+ <my:currentWWUrl action="managedRepositories" namespace="/admin">Managed Repositories</my:currentWWUrl>
+ </li>
+ <li class="none">
+ <my:currentWWUrl action="proxiedRepositories" namespace="/admin">Proxied Repositories</my:currentWWUrl>
+ </li>
+
+ <%-- TODO: add back after synced repos are implemented
+ <li class="none">
+ <my:currentWWUrl action="syncedRepositories" namespace="/admin">Synced Repositories</my:currentWWUrl>
+ </li>
+ --%>
+ </ul>
+ </pss:ifAuthorized>
+
+ </div>
+</div>
+
+<div id="bodyColumn">
+ <div id="contentBox">
+ <decorator:body/>
+ </div>
+</div>
+
+<div class="clear">
+ <hr/>
+</div>
+
+<%
+ int inceptionYear = 2005;
+ int currentYear = Calendar.getInstance().get( Calendar.YEAR );
+ String copyrightRange = String.valueOf( inceptionYear );
+ if ( inceptionYear != currentYear )
+ {
+ copyrightRange = copyrightRange + "-" + String.valueOf( currentYear );
+ }
+%>
+<div id="footer">
+ <div class="xright">©
+ Copyright © <%= copyrightRange %> Apache Software Foundation
+ </div>
+
+ <div class="clear">
+ <hr/>
+
+ </div>
+</div>
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+ <title>Find Artifact</title>
+ <ww:head/>
+</head>
+
+<body onload="document.checksumSearch.file.disabled = false">
+
+<h1>Find Artifact</h1>
+
+<div id="contentArea">
+ <div id="searchBox">
+ <script type="text/javascript">
+ function generateMd5( file, defVal )
+ {
+ if ( file )
+ {
+ var s = document.ChecksumApplet.generateMd5(file);
+ // If there is a space, it's an error message, not a checksum
+ if ( s.indexOf(" ") >= 0 )
+ {
+ alert(s);
+ return "";
+ }
+ else
+ return s;
+ }
+ return defVal;
+ }
+ </script>
+
+ <noscript>
+ <span class="errorMessage">JavaScript is disabled: using the file browser will not work.</span>
+ </noscript>
+
+ <ww:form method="POST" action="checksumSearch" namespace="/"
+ onsubmit="this.md5.value = generateMd5(this.file.value,this.md5.value); this.file.disabled = true">
+ <tr>
+ <td class="tdLabel"><label for="checksumSearch_file" class="label">Search for:</label></td>
+ <td>
+ <input type="file" name="file" size="50" value="" id="checksumSearch_file"/>
+ </td>
+ </tr>
+ <ww:textfield label="Checksum" size="50" name="md5"/>
+ <ww:submit value="Go!"/>
+ </ww:form>
+
+ <p>
+ Select the file you would like to locate in the remote repository.
+ The entire file will
+ <b>not</b>
+ be uploaded to the server. See the progress bar below for progress of
+ locally creating a checksum that is uploaded to the server after you hit "Go!".
+ <ww:actionerror/>
+ </p>
+
+ <p>
+ <applet code="org/apache/maven/archiva/applet/ChecksumApplet.class"
+ archive="archiva-applet.jar"
+ width="400" height="20" name="ChecksumApplet">
+ </applet>
+ </p>
+
+ </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<html>
+<head>
+ <title>Error Occurred</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Error Occurred</h1>
+
+<ww:actionerror/>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+
+<%-- TODO: paginate! --%>
+<c:forEach items="${dependencies}" var="dependency">
+ <h3 class="artifact-title">
+ <my:showArtifactTitle groupId="${dependency.groupId}" artifactId="${dependency.artifactId}"
+ version="${dependency.version}"/>
+
+ </h3>
+
+ <p>
+ <my:showArtifactLink groupId="${dependency.groupId}" artifactId="${dependency.artifactId}"
+ version="${dependency.version}" versions="${dependency.versions}" scope="${dependency.scope}"
+ classifier="${dependency.classifier}"/>
+ </p>
+</c:forEach>
+<c:if test="${empty(dependencies)}">
+ <strong>No results</strong>
+</c:if>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
+
+<p>
+ <archiva:groupIdLink var="${model.groupId}" includeTop="true" />
+
+ <c:set var="url">
+ <ww:url action="browseArtifact" namespace="/">
+ <ww:param name="groupId" value="%{'${model.groupId}'}"/>
+ <ww:param name="artifactId" value="%{'${model.artifactId}'}"/>
+ </ww:url>
+ </c:set>
+ <a href="${url}">${model.artifactId}</a> /
+ <strong>${model.version}</strong>
+
+ <%-- TODO: new versions?
+ (<strong class="statusFailed">Newer version available:</strong>
+ <a href="artifact.html">2.0.3</a>)
+ --%>
+</p>
+
+<c:if test="${!empty(model.description)}">
+ <blockquote>${model.description}</blockquote>
+</c:if>
+
+<table class="infoTable">
+ <tr>
+ <th>Group ID</th>
+ <td>${model.groupId}</td>
+ </tr>
+ <tr>
+ <th>Artifact ID</th>
+ <td>${model.artifactId}</td>
+ </tr>
+ <tr>
+ <th>Version</th>
+ <td>${model.version}</td>
+ </tr>
+ <tr>
+ <th>Packaging</th>
+ <td><code>${model.packaging}</code></td>
+ </tr>
+ <%-- TODO: derivatives
+ <tr>
+ <th>Derivatives</th>
+ <td>
+ <a href="#">Source</a>
+ |
+ <a href="#">Javadoc</a>
+ </td>
+ </tr>
+ --%>
+ <c:if test="${model.parent != null}">
+ <tr>
+ <th>Parent</th>
+ <td>
+ ${model.parent.groupId} ${model.parent.artifactId} ${model.parent.version}
+ <c:set var="url">
+ <ww:url action="showArtifact" namespace="/">
+ <ww:param name="groupId" value="%{'${model.parent.groupId}'}"/>
+ <ww:param name="artifactId" value="%{'${model.parent.artifactId}'}"/>
+ <ww:param name="version" value="%{'${model.parent.version}'}"/>
+ </ww:url>
+ </c:set>
+ (<a href="${url}">View</a>)
+ </td>
+ </tr>
+ </c:if>
+ <%-- TODO: deployment timestamp
+ <tr>
+ <th>Deployment Date</th>
+ <td>
+ 15 Jan 2006, 20:38:00 +1000
+ </td>
+ </tr>
+ --%>
+ <%-- TODO: origin
+ <tr>
+ <th>Origin</th>
+ <td>
+ <a href="TODO">Apache Repository</a>
+ </td>
+ </tr>
+ --%>
+</table>
+
+<c:if test="${model.packaging != 'pom'}">
+ <h2>POM Dependency Snippet</h2>
+<pre class="pom">
+ <dependency>
+ <groupId>${model.groupId}</groupId>
+ <artifactId>${model.artifactId}</artifactId>
+ <version>${model.version}</version><c:if test="${model.packaging != 'jar'}">
+ <type>${model.packaging}</type></c:if>
+ </dependency>
+</pre>
+</c:if>
+
+<c:if test="${!empty(model.url) || model.organization != null || !empty(model.licenses)
+ || model.issueManagement != null || model.ciManagement != null}">
+
+ <h2>Other Details</h2>
+ <table class="infoTable">
+ <c:if test="${!empty(model.url)}">
+ <tr>
+ <th>URL</th>
+ <td>
+ <a href="${model.url}">${model.url}</a>
+ </td>
+ </tr>
+ </c:if>
+ <c:if test="${model.organization != null}">
+ <tr>
+ <th>Organisation</th>
+ <td>
+ <c:choose>
+ <c:when test="${model.organization != null}">
+ <a href="${model.organization.url}">${model.organization.name}</a>
+ </c:when>
+ <c:otherwise>
+ ${model.organization.name}
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ </c:if>
+ <c:if test="${!empty(model.licenses)}">
+ <c:forEach items="${model.licenses}" var="license">
+ <tr>
+ <th>License</th>
+ <td>
+ <c:choose>
+ <c:when test="${!empty(license.url)}">
+ <a href="${license.url}">${license.name}</a>
+ </c:when>
+ <c:otherwise>
+ ${license.name}
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ </c:forEach>
+ </c:if>
+ <c:if test="${model.issueManagement != null}">
+ <tr>
+ <th>Issue Tracker</th>
+ <td>
+ <c:choose>
+ <c:when test="${!empty(model.issueManagement.url)}">
+ <a href="${model.issueManagement.url}">${model.issueManagement.system}</a>
+ </c:when>
+ <c:otherwise>
+ ${model.issueManagement.system}
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ </c:if>
+ <c:if test="${model.ciManagement != null}">
+ <tr>
+ <th>Continuous Integration</th>
+ <td>
+ <c:choose>
+ <c:when test="${!empty(model.ciManagement.url)}">
+ <a href="${model.ciManagement.url}">${model.ciManagement.system}</a>
+ </c:when>
+ <c:otherwise>
+ ${model.ciManagement.system}
+ </c:otherwise>
+ </c:choose>
+ </td>
+ </tr>
+ </c:if>
+ </table>
+</c:if>
+
+<c:if test="${model.scm != null}">
+ <h2>SCM</h2>
+ <table class="infoTable">
+ <c:if test="${!empty(model.scm.connection)}">
+ <tr>
+ <th>Connection</th>
+ <td>
+ <code>${model.scm.connection}</code>
+ </td>
+ </tr>
+ </c:if>
+ <c:if test="${!empty(model.scm.developerConnection)}">
+ <tr>
+ <th>Dev. Connection</th>
+ <td>
+ <code>${model.scm.developerConnection}</code>
+ </td>
+ </tr>
+ </c:if>
+ <c:if test="${!empty(model.scm.url)}">
+ <tr>
+ <th>Viewer</th>
+ <td>
+ <a href="${model.scm.url}">${model.scm.url}</a>
+ </td>
+ </tr>
+ </c:if>
+ </table>
+</c:if>
+
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+
+<c:forEach items="${reports}" var="report">
+ <h3>
+ ${report.groupId} : ${report.artifactId} : ${report.version} : ${report.classifier} : ${report.type}
+ </h3>
+ <ul>
+ <c:forEach items="${repor.results}" var="result">
+ <li>
+ <b>${result.reason}</b>
+ </li>
+ </c:forEach>
+ </ul>
+</c:forEach>
+<c:if test="${empty(reports)}">
+ <strong>No reports for this artifact.</strong>
+</c:if>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+
+<ul class="dependencyTree">
+<c:set var="prevDepth" value="1"/>
+<ww:set name="dependencyTree" value="dependencyTree"/>
+<c:forEach items="${dependencyTree}" var="node">
+ <c:choose>
+ <c:when test="${node.depth < prevDepth}">
+ </ul>
+ <li>
+ </c:when>
+ <c:when test="${node.depth > prevDepth}">
+ <ul>
+ <li>
+ </c:when>
+ <c:otherwise>
+ <li>
+ </c:otherwise>
+ </c:choose>
+ <my:showArtifactLink groupId="${node.artifact.groupId}" artifactId="${node.artifact.artifactId}"
+ version="${node.artifact.version}"/>
+ </li>
+ <c:set var="prevDepth" value="${node.depth}"/>
+</c:forEach>
+</ul>
+
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+
+<c:forEach items="${mailingLists}" var="mailingList">
+ <h3>
+ ${mailingList.name}
+ </h3>
+ <%-- TODO: description
+ <p>
+ Description blah blah blah
+ </p>
+ --%>
+ <ul>
+ <c:if test="${!empty(mailingList.subscribe)}">
+ <li>
+ <b>Subscribe:</b>
+ <a href="mailto:${mailingList.subscribe}">${mailingList.subscribe}</a>
+ </li>
+ </c:if>
+ <c:if test="${!empty(mailingList.post)}">
+ <li>
+ <b>Post:</b>
+ <a href="mailto:${mailingList.post}">${mailingList.post}</a>
+ </li>
+ </c:if>
+ <c:if test="${!empty(mailingList.unsubscribe)}">
+ <li>
+ <b>Unsubscribe:</b>
+ <a href="mailto:${mailingList.unsubscribe}">${mailingList.unsubscribe}</a>
+ </li>
+ </c:if>
+ <%-- TODO: not in the POM yet
+ <li>
+ <b>List owner:</b>
+ <a href="mailto:${mailingList.owner}">${mailingList.owner}</a>
+ </li>
+ --%>
+ <c:if test="${!empty(mailingList.archive)}">
+ <li>
+ <b>Archive:</b>
+ <ul>
+ <li>
+ <a href="${mailingList.archive}">${mailingList.archive}</a>
+ </li>
+ </ul>
+ </li>
+ </c:if>
+ <c:if test="${!empty(mailingList.otherArchives)}">
+ <li>
+ <b>Other Archives:</b>
+ <ul>
+ <c:forEach items="${mailingList.otherArchives}" var="archive">
+ <li>
+ <a href="${archive}">${archive}</a>
+ </li>
+ </c:forEach>
+ </ul>
+ </li>
+ </c:if>
+ </ul>
+</c:forEach>
+<c:if test="${empty(mailingLists)}">
+ <strong>No mailing lists</strong>
+</c:if>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<div id="searchBox">
+ <ww:form method="get" action="quickSearch" validate="true">
+ <ww:textfield label="Search for" size="50" name="q"/>
+ <ww:submit label="Go!"/>
+ </ww:form>
+
+ <script type="text/javascript">
+ document.getElementById("quickSearch_q").focus();
+ </script>
+
+ <p>
+ Enter your search terms. A variety of data will be searched for your keywords.
+ <ww:actionerror/>
+ </p>
+</div>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<html>
+<head>
+ <title>Quick Search</title>
+ <ww:head/>
+</head>
+
+<ww:if test="%{infoMessage != null}">
+ <p>${infoMessage}</p>
+</ww:if>
+
+<body>
+
+<h1>Search</h1>
+
+<div id="contentArea">
+ <%@ include file="/WEB-INF/jsp/include/quickSearchForm.jspf" %>
+</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+
+<html>
+<head>
+ <title>Reports</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Reports</h1>
+
+<div id="contentArea">
+
+<c:forEach items="${reports}" var="report">
+ <h3>
+ ${report.groupId} : ${report.artifactId} : ${report.version} : ${report.classifier} : ${report.type}
+ </h3>
+ <ul>
+ <c:forEach items="${repor.results}" var="result">
+ <li>
+ <b>${result.reason}</b>
+ </li>
+ </c:forEach>
+ </ul>
+</c:forEach>
+<c:if test="${empty(reports)}">
+ <strong>No reports for any artifact.</strong>
+</c:if>
+
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib uri="/webwork" prefix="ww" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+
+<html>
+<head>
+ <title>Search Results</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<h1>Search</h1>
+
+<div id="contentArea">
+ <div id="searchBox">
+ <%@ include file="/WEB-INF/jsp/include/quickSearchForm.jspf" %>
+ </div>
+
+ <h1>Results</h1>
+
+ <div id="resultsBox">
+ <ww:set name="searchResults" value="searchResults"/>
+ <c:forEach items="${searchResults}" var="record" varStatus="i">
+
+
+ <h3 class="artifact-title">
+ <my:showArtifactTitle groupId="${record.groupId}" artifactId="${record.artifactId}"
+ version="${record.version}"/>
+ </h3>
+
+ <p>
+ <my:showArtifactLink groupId="${record.groupId}" artifactId="${record.artifactId}"
+ version="${record.version}" versions="${record.versions}"/>
+
+ <%-- TODO: hits
+ <table border="1px" width="100%" cellspacing="0">
+ <c:forEach items="${result.fieldMatchesEntrySet}" var="entry">
+ <tr>
+ <td valign="top" width="15%" align="right"><c:out value="${entry.key}"/></td>
+ <td valign="top">
+ <c:forEach items="${entry.value}" var="item">
+ <c:out value="${item}" />
+ </c:forEach>
+ <br/>
+ </td>
+ </tr>
+ </c:forEach>
+ </table>
+ </td>
+ <td>
+
+ <code>org.apache.maven</code>
+ (package)
+ <br/>
+ <code>org.apache.maven.model</code>
+ (package)
+ </td>
+ <td>
+ <a href="artifact.html">Details</a>
+ </td>
+ --%>
+ </p>
+ </c:forEach>
+ </div>
+</div>
+</body>
+</html>
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
+<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
+<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
+
+<html>
+<head>
+ <title>Browse Repository</title>
+ <ww:head/>
+</head>
+
+<body>
+
+<ww:set name="model" value="model"/>
+<c:choose>
+ <c:when test="${model.packaging == 'maven-plugin'}">
+ <c:url var="imageUrl" value="/images/mavenplugin.gif"/>
+ <c:set var="packageName">Maven Plugin</c:set>
+ </c:when>
+ <c:when test="${model.packaging == 'pom'}">
+ <c:url var="imageUrl" value="/images/pom.gif"/>
+ <c:set var="packageName">POM</c:set>
+ </c:when>
+ <%-- These types aren't usually set in the POM yet, so we fudge them for the well known ones --%>
+ <c:when test="${model.packaging == 'maven-archetype' or model.groupId == 'org.apache.maven.archetypes'}">
+ <c:url var="imageUrl" value="/images/archetype.gif"/>
+ <c:set var="packageName">Maven Archetype</c:set>
+ </c:when>
+ <c:when test="${model.packaging == 'maven-skin' or model.groupId == 'org.apache.maven.skins'}">
+ <c:url var="imageUrl" value="/images/skin.gif"/>
+ <c:set var="packageName">Maven Skin</c:set>
+ </c:when>
+ <%-- Must be last so that the above get picked up if possible --%>
+ <c:when test="${model.packaging == 'jar'}">
+ <c:url var="imageUrl" value="/images/jar.gif"/>
+ <c:set var="packageName">JAR</c:set>
+ </c:when>
+ <c:otherwise>
+ <c:url var="imageUrl" value="/images/other.gif"/>
+ <c:set var="packageName"></c:set>
+ </c:otherwise>
+</c:choose>
+<img src="${imageUrl}" width="66" height="66" alt="${packageName}" title="${packageName}" style="float: left"/>
+
+<h1>
+ <c:choose>
+ <c:when test="${empty(model.name)}">
+ ${model.artifactId}
+ </c:when>
+ <c:otherwise>
+ ${model.name}
+ </c:otherwise>
+ </c:choose>
+</h1>
+
+<div id="contentArea">
+ <div id="tabs">
+ <span>
+ <c:set var="url">
+ <ww:url action="showArtifact">
+ <ww:param name="groupId" value="%{groupId}"/>
+ <ww:param name="artifactId" value="%{artifactId}"/>
+ <ww:param name="version" value="%{version}"/>
+ </ww:url>
+ </c:set>
+ <my:currentWWUrl url="${url}">Info</my:currentWWUrl>
+ <c:set var="url">
+ <ww:url action="showArtifactDependencies">
+ <ww:param name="groupId" value="%{groupId}"/>
+ <ww:param name="artifactId" value="%{artifactId}"/>
+ <ww:param name="version" value="%{version}"/>
+ </ww:url>
+ </c:set>
+ <my:currentWWUrl url="${url}">Dependencies</my:currentWWUrl>
+ <c:set var="url">
+ <ww:url action="showArtifactDependencyTree">
+ <ww:param name="groupId" value="%{groupId}"/>
+ <ww:param name="artifactId" value="%{artifactId}"/>
+ <ww:param name="version" value="%{version}"/>
+ </ww:url>
+ </c:set>
+ <my:currentWWUrl url="${url}">Dependency Tree</my:currentWWUrl>
+ <c:set var="url">
+ <ww:url action="showArtifactDependees">
+ <ww:param name="groupId" value="%{groupId}"/>
+ <ww:param name="artifactId" value="%{artifactId}"/>
+ <ww:param name="version" value="%{version}"/>
+ </ww:url>
+ </c:set>
+ <my:currentWWUrl url="${url}">Used By</my:currentWWUrl>
+ <c:set var="url">
+ <ww:url action="showArtifactMailingLists">
+ <ww:param name="groupId" value="%{groupId}"/>
+ <ww:param name="artifactId" value="%{artifactId}"/>
+ <ww:param name="version" value="%{version}"/>
+ </ww:url>
+ </c:set>
+ <my:currentWWUrl url="${url}">Mailing Lists</my:currentWWUrl>
+ <pss:ifAnyAuthorized permissions="archiva-access-reports">
+ <c:set var="url">
+ <ww:url action="showArtifactReports">
+ <ww:param name="groupId" value="%{groupId}"/>
+ <ww:param name="artifactId" value="%{artifactId}"/>
+ <ww:param name="version" value="%{version}"/>
+ </ww:url>
+ </c:set>
+ <my:currentWWUrl url="${url}">Reports</my:currentWWUrl>
+ </pss:ifAnyAuthorized>
+
+ </span>
+ </div>
+
+<div class="sidebar3">
+ <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${Version}" />
+</div>
+
+ <%-- TODO: perhaps using ajax? --%>
+ <%-- TODO: panels? this is ugly as is! --%>
+ <div id="tabArea">
+ <c:choose>
+ <c:when test="${dependencies != null}">
+ <%@ include file="/WEB-INF/jsp/include/artifactDependencies.jspf" %>
+ </c:when>
+ <c:when test="${dependencyTree != null}">
+ <%@ include file="/WEB-INF/jsp/include/dependencyTree.jspf" %>
+ </c:when>
+ <c:when test="${mailingLists != null}">
+ <%@ include file="/WEB-INF/jsp/include/mailingLists.jspf" %>
+ </c:when>
+ <c:when test="${reports != null}">
+ <%@ include file="/WEB-INF/jsp/include/artifactReports.jspf" %>
+ </c:when>
+ <c:otherwise>
+ <%@ include file="/WEB-INF/jsp/include/artifactInfo.jspf" %>
+ </c:otherwise>
+ </c:choose>
+ </div>
+</div>
+
+</body>
+</html>
--- /dev/null
+<%--\r
+ ~ Licensed to the Apache Software Foundation (ASF) under one\r
+ ~ or more contributor license agreements. See the NOTICE file\r
+ ~ distributed with this work for additional information\r
+ ~ regarding copyright ownership. The ASF licenses this file\r
+ ~ to you under the Apache License, Version 2.0 (the\r
+ ~ "License"); you may not use this file except in compliance\r
+ ~ with the License. You may obtain a copy of the License at\r
+ ~\r
+ ~ http://www.apache.org/licenses/LICENSE-2.0\r
+ ~\r
+ ~ Unless required by applicable law or agreed to in writing,\r
+ ~ software distributed under the License is distributed on an\r
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r
+ ~ KIND, either express or implied. See the License for the\r
+ ~ specific language governing permissions and limitations\r
+ ~ under the License.\r
+ --%>\r
+\r
+<%@ taglib uri="/webwork" prefix="ww" %>\r
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\r
+<%@ attribute name="action" %>\r
+<%@ attribute name="namespace" %>\r
+<%@ attribute name="url" %>\r
+\r
+<c:set var="currentUrl">\r
+ <ww:url/>\r
+</c:set>\r
+<c:if test="${!empty(action) && !empty(namespace)}">\r
+ <c:set var="url">\r
+ <ww:url action="${action}" namespace="${namespace}"/>\r
+ </c:set>\r
+</c:if>\r
+<c:set var="text">\r
+ <jsp:doBody/>\r
+</c:set>\r
+<c:choose>\r
+ <c:when test="${currentUrl == url}">\r
+ <b>${text}</b>\r
+ </c:when>\r
+ <c:otherwise>\r
+ <a href="${url}">${text}</a>\r
+ </c:otherwise>\r
+</c:choose>\r
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%-- TODO: this could perhaps just be a i18n call --%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ attribute name="policy" required="true" %>
+<%@ attribute name="interval" %>
+
+<c:choose>
+ <c:when test="${policy == 'disabled'}">
+ Disabled
+ </c:when>
+ <c:when test="${policy == 'always'}">
+ Updated every request
+ </c:when>
+ <c:when test="${policy == 'hourly'}">
+ Updated hourly
+ </c:when>
+ <c:when test="${policy == 'daily'}">
+ Updated daily
+ </c:when>
+ <c:when test="${policy == 'interval'}">
+ Updated every ${interval} minutes
+ </c:when>
+</c:choose>
\ No newline at end of file
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
+<%@ attribute name="groupId" required="true" %>
+<%@ attribute name="artifactId" %>
+<%@ attribute name="version" %>
+<%@ attribute name="classifier" %>
+<%@ attribute name="scope" %>
+<%@ attribute name="versions" type="java.util.List" %>
+
+<span class="artifact-link">
+ <archiva:groupIdLink var="${model.groupId}" includeTop="true" />
+
+ <c:if test="${!empty(artifactId)}">
+ <c:set var="url">
+ <ww:url action="browseArtifact" namespace="/">
+ <ww:param name="groupId" value="%{'${groupId}'}"/>
+ <ww:param name="artifactId" value="%{'${artifactId}'}"/>
+ </ww:url>
+ </c:set>
+ / <a href="${url}">${artifactId}</a>
+ </c:if>
+ | <strong>Version(s):</strong>
+ <c:choose>
+ <c:when test="${!empty(version)}">
+ <c:set var="url">
+ <ww:url action="showArtifact" namespace="/">
+ <ww:param name="groupId" value="%{'${groupId}'}"/>
+ <ww:param name="artifactId" value="%{'${artifactId}'}"/>
+ <c:if test="${!empty(version)}">
+ <ww:param name="version" value="%{'${version}'}"/>
+ </c:if>
+ </ww:url>
+ </c:set>
+ <a href="${url}">${version}</a>
+ </c:when>
+ <c:otherwise>
+ <c:forEach items="${versions}" var="v" varStatus="i">
+ <c:set var="url">
+ <ww:url action="showArtifact" namespace="/">
+ <ww:param name="groupId" value="%{'${groupId}'}"/>
+ <ww:param name="artifactId" value="%{'${artifactId}'}"/>
+ <ww:param name="version" value="%{'${v}'}"/>
+ </ww:url>
+ </c:set>
+ <a href="${url}">${v}</a>
+ <c:if test="${!i.last}">,</c:if>
+ </c:forEach>
+ </c:otherwise>
+ </c:choose>
+ <c:if test="${!empty(scope)}">
+ | <strong>Scope:</strong> ${scope}
+ </c:if>
+ <c:if test="${!empty(classifier)}">
+ | <strong>Classifier:</strong> ${classifier}
+ </c:if>
+</span>
--- /dev/null
+<%--\r
+ ~ Licensed to the Apache Software Foundation (ASF) under one\r
+ ~ or more contributor license agreements. See the NOTICE file\r
+ ~ distributed with this work for additional information\r
+ ~ regarding copyright ownership. The ASF licenses this file\r
+ ~ to you under the Apache License, Version 2.0 (the\r
+ ~ "License"); you may not use this file except in compliance\r
+ ~ with the License. You may obtain a copy of the License at\r
+ ~\r
+ ~ http://www.apache.org/licenses/LICENSE-2.0\r
+ ~\r
+ ~ Unless required by applicable law or agreed to in writing,\r
+ ~ software distributed under the License is distributed on an\r
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r
+ ~ KIND, either express or implied. See the License for the\r
+ ~ specific language governing permissions and limitations\r
+ ~ under the License.\r
+ --%>\r
+\r
+<%@ taglib prefix="ww" uri="/webwork" %>\r
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\r
+<%@ attribute name="groupId" required="true" %>\r
+<%@ attribute name="artifactId" %>\r
+<%@ attribute name="version" %>\r
+\r
+ <span class="artifact-title">\r
+ <c:set var="url">\r
+ <c:choose>\r
+ <c:when test="${!empty(version)}">\r
+ <ww:url action="showArtifact" namespace="/">\r
+ <ww:param name="groupId" value="%{'${groupId}'}"/>\r
+ <ww:param name="artifactId" value="%{'${artifactId}'}"/>\r
+ <ww:param name="version" value="%{'${version}'}"/>\r
+ </ww:url>\r
+ </c:when>\r
+ <c:otherwise>\r
+ <ww:url action="browseArtifact" namespace="/">\r
+ <ww:param name="groupId" value="%{'${groupId}'}"/>\r
+ <ww:param name="artifactId" value="%{'${artifactId}'}"/>\r
+ </ww:url>\r
+ </c:otherwise>\r
+ </c:choose>\r
+ </c:set>\r
+ <%-- TODO: showing the name and description would be nice, but that would require loading the POMs --%>\r
+ <a href="${url}">${artifactId}</a>\r
+ </span>\r
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <display-name>Maven Archiva</display-name>
+
+ <filter>
+ <filter-name>webwork-cleanup</filter-name>
+ <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>
+ </filter>
+
+ <filter>
+ <filter-name>sitemesh</filter-name>
+ <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
+ </filter>
+
+ <filter>
+ <filter-name>webwork</filter-name>
+ <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
+ </filter>
+
+ <!-- this must be before the sitemesh filter -->
+ <filter-mapping>
+ <filter-name>webwork-cleanup</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name>sitemesh</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name>webwork</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <listener>
+ <listener-class>org.codehaus.plexus.xwork.PlexusLifecycleListener</listener-class>
+ </listener>
+
+ <servlet>
+ <servlet-name>RepositoryServlet</servlet-name>
+ <servlet-class>org.apache.maven.archiva.web.repository.RepositoryServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>RepositoryServlet</servlet-name>
+ <url-pattern>/repository/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+body {
+ margin: 0px;
+ padding: 0px;
+}
+
+img {
+ border: none;
+}
+
+table {
+ padding: 0px;
+ width: 100%;
+ margin-left: -2px;
+ margin-right: -2px;
+}
+
+acronym {
+ cursor: help;
+ border-bottom: 1px dotted #feb;
+}
+
+table.bodyTable th, table.bodyTable td {
+ padding: 2px 4px 2px 4px;
+ vertical-align: top;
+}
+
+div.clear {
+ clear: both;
+ visibility: hidden;
+}
+
+div.clear hr {
+ display: none;
+}
+
+#bannerLeft, #bannerRight {
+ font-size: xx-large;
+ font-weight: bold;
+}
+
+#bannerLeft img, #bannerRight img {
+ margin: 0px;
+}
+
+.xleft, #bannerLeft img {
+ float: left;
+ text-shadow: #7CFC00;
+}
+
+.xright, #bannerRight img {
+ float: right;
+ text-shadow: #7CFC00;
+}
+
+#banner {
+ padding: 0px;
+}
+
+#banner img {
+ border: none;
+}
+
+#breadcrumbs {
+ padding: 3px 10px 3px 10px;
+}
+
+#leftColumn {
+ height: 315px;
+ width: 170px;
+ float: left;
+ overflow: auto;
+}
+
+#bodyColumn {
+ margin-right: 1.5em;
+ margin-left: 197px;
+}
+
+#legend {
+ padding: 8px 0 8px 0;
+}
+
+#navcolumn {
+ padding: 8px 4px 0 8px;
+}
+
+#navcolumn h5 {
+ margin: 0;
+ padding: 0;
+ font-size: small;
+}
+
+#navcolumn ul {
+ margin: 0;
+ padding: 0;
+ font-size: small;
+}
+
+#navcolumn li {
+ list-style-type: none;
+ background-image: none;
+ background-repeat: no-repeat;
+ background-position: 0 0.4em;
+ padding-left: 16px;
+ list-style-position: outside;
+ line-height: 1.2em;
+ font-size: smaller;
+}
+
+#navcolumn li.expanded {
+ background-image: url( ../images/expanded.gif );
+}
+
+#navcolumn li.collapsed {
+ background-image: url( ../images/collapsed.gif );
+}
+
+#poweredBy {
+ text-align: center;
+}
+
+#navcolumn img {
+ margin-top: 10px;
+ margin-bottom: 3px;
+}
+
+#poweredBy img {
+ display: block;
+ margin: 20px 0 20px 17px;
+ border: 1px solid black;
+ width: 90px;
+ height: 30px;
+}
+
+#search img {
+ margin: 0px;
+ display: block;
+}
+
+#search #q, #search #btnG {
+ border: 1px solid #999;
+ margin-bottom: 10px;
+}
+
+#search form {
+ margin: 0px;
+}
+
+#lastPublished {
+ font-size: x-small;
+}
+
+.navSection {
+ margin-bottom: 2px;
+ padding: 8px;
+}
+
+.navSectionHead {
+ font-weight: bold;
+ font-size: x-small;
+}
+
+.section {
+ padding: 4px;
+}
+
+#footer {
+ padding: 3px 10px 3px 10px;
+ font-size: x-small;
+}
+
+#breadcrumbs {
+ font-size: x-small;
+ margin: 0pt;
+}
+
+.source {
+ padding: 12px;
+ margin: 1em 7px 1em 7px;
+}
+
+.source pre {
+ margin: 0px;
+ padding: 0px;
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+body {
+ padding: 0 0 10px 0;
+}
+
+body, td, th, select, input, li {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ font-size: 13px;
+}
+
+select, input {
+ font-size: x-small;
+}
+
+th {
+ text-align: right;
+ padding-right: 1em;
+ font-size: x-small;
+ vertical-align: top;
+}
+
+.infoTable th {
+ width: 15em;
+}
+
+#contentBox h1 {
+ background-image: url( ../images/arrow.gif );
+ background-repeat: no-repeat;
+ background-position: left bottom;
+ border-bottom: 1px solid #DFDEDE;
+ padding: 0 0 1px 23px;
+ margin-bottom: 0.5em;
+ color: #333;
+ voice-family: inherit;
+ font-size: medium !important;
+}
+
+#contentBox h2 {
+ border-bottom: 1px solid #DFDEDE;
+ padding: 0 0 1px 0;
+ margin-bottom: 0.5em;
+ color: #333;
+ voice-family: inherit;
+ font-size: small !important;
+}
+
+#contentBox h3 {
+ border-bottom: 1px solid #DFDEDE;
+ padding: 0 0 1px 0;
+ margin-bottom: 0.5em;
+ color: #333;
+ voice-family: inherit;
+ font-size: small !important;
+ margin-left: 2em;
+}
+
+table {
+ width: auto;
+}
+
+code {
+ font-family: Courier, monospace;
+ font-size: 13px;
+}
+
+#legend li.externalLink {
+ background: url( ../images/external.png ) left top no-repeat;
+ padding-left: 18px;
+}
+
+a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
+ background: url( ../images/external.png ) right center no-repeat;
+ padding-right: 18px;
+}
+
+#legend li.newWindow {
+ background: url( ../images/newwindow.png ) left top no-repeat;
+ padding-left: 18px;
+}
+
+a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover {
+ background: url( ../images/newwindow.png ) right center no-repeat;
+ padding-right: 18px;
+}
+
+p {
+ line-height: 1.3em;
+ font-size: small;
+}
+
+#breadcrumbs {
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #999;
+ background-color: #F3B455;
+ padding: 2px 8px;
+}
+
+#navcolumn h5 {
+ color: gray;
+ font-weight: bold;
+ font-size: 11px;
+ padding: 10px 0 1px 19px;
+}
+
+.source {
+ border: 1px solid #999;
+}
+
+dl {
+ padding: 4px 4px 4px 6px;
+ border: 1px solid #aaa;
+ background-color: #ffc;
+}
+
+dt {
+ color: #900;
+}
+
+#organizationLogo img, #projectLogo img, #projectLogo span {
+ margin: 8px;
+}
+
+#banner {
+ border-bottom: 1px solid #fff;
+ padding: 8px;
+}
+
+#breadcrumbs a:link {
+ text-decoration: none;
+}
+
+#breadcrumbs a:visited {
+ text-decoration: none;
+ color: #333
+}
+
+#breadcrumbs a:hover {
+ text-decoration: none;
+ color: white
+}
+
+.errormark, .warningmark, .donemark, .infomark {
+ background: url( ../images/icon_error_sml.gif ) no-repeat;
+}
+
+.warningmark {
+ background-image: url( ../images/icon_warning_sml.gif );
+}
+
+.donemark {
+ background-image: url( ../images/icon_success_sml.gif );
+}
+
+.infomark {
+ background-image: url( ../images/icon_info_sml.gif );
+}
+
+.booleanIcon {
+ padding-left: 20px;
+ height: 20px;
+}
+
+pre.pom {
+ font-size: 0.9em;
+ border: 1px solid #ddddff;
+ background-color: #f8f8ff;
+ padding: 5px;
+}
+
+pre.pom code {
+ font-size: 0.9em;
+}
+
+#leftColumn {
+ padding: 4px 4px 4px 4px;
+ overflow: hidden;
+}
+
+#navcolumn {
+ padding: 6px 0 0 2px;
+}
+
+#navcolumn li {
+ font-size: 9px;
+ text-indent: 19px;
+ line-height: 24px;
+ height: 25px;
+ width: 161px;
+ background-image: url( ../images/super.gif );
+ background-position: 0 0;
+ background-repeat: no-repeat;
+ display: block;
+ padding-left: 0;
+}
+
+#navcolumn li li {
+ padding-left: 16px;
+ background: none;
+ display: block;
+}
+
+#navcolumn li li a:hover {
+ color: black !important;
+ background: none;
+ display: block;
+}
+
+#navcolumn li li a:active {
+ color: red !important;
+ background: none;
+ display: block;
+}
+
+#navcolumn li.collapsed {
+ background-image: url( ../images/super.gif );
+}
+
+#navcolumn li.expanded {
+ background-image: url( ../images/super.gif );
+ height: inherit;
+}
+
+#navcolumn li a:link {
+ color: #666;
+ display: block;
+}
+
+#navcolumn li a:hover {
+ color: #fff !important;
+ background: url( ../images/super_hl.gif ) 0 -25px no-repeat;
+ display: block;
+}
+
+#navcolumn li a:active {
+ color: #fff !important;
+ background: url( ../images/super_hl.gif ) 0 -50px no-repeat;
+ display: block;
+}
+
+#navcolumn li a:visited {
+ color: #666;
+ display: block;
+}
+
+#navcolumn li ul li {
+ color: #333 !important;
+ text-indent: 30px !important;
+ line-height: 20px !important;
+ height: 20px !important;
+ background-image: url( ../images/supersub.gif ) !important;
+ font-size: 9px;
+ width: 161px;
+ background-repeat: no-repeat;
+ display: block;
+ padding-left: 0;
+}
+
+#navcolumn li ul li a:hover {
+ color: #fff !important;
+ background: url( ../images/super_hl_sub.gif ) 0 -20px no-repeat;
+ background-position: right;
+ width: 161px;
+ display: block;
+}
+
+#footer {
+ background: url( ../images/footerborder.gif ) 0 5px repeat-x;
+ padding: 14px 4px 12px 4px;
+ margin-top: 2em;
+}
+
+a:link, a:visited {
+ color: #333;
+}
+
+#navcolumn a {
+ text-decoration: none;
+}
+
+a:active, a:hover {
+ color: #f30;
+}
+
+blockquote {
+ border-left: 1px solid #DFDEDE;
+ padding-left: 1em;
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn {
+ display: none !important;
+}
+
+#bodyColumn, body.docs div.docs {
+ margin: 0 !important;
+ border: none !important
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+.sidebar3 {
+ width: 10em;
+ float: right;
+ text-align: center;
+}
+
+#sidebarb {
+ font-size: small;
+ text-align: center;
+ padding: 10px 10px 10px 10px;
+ border: 1px #DFDEDE solid;
+ width: 10em;
+}
+
+#sidebar {
+ float: right;
+ font-size: small;
+ margin: 10px;
+ padding: 10px;
+ border: 1px #DFDEDE solid;
+ width: 10em;
+}
+
+.download {
+ float: right;
+ font-size: small;
+ font-weight: bold;
+ xmargin: 0px auto;
+ margin: 15px auto 0px auto;
+ height: auto;
+ width: 150px;
+ min-width: 120px;
+ display: block;
+}
+
+.download .hd .c,
+.download .ft .c {
+ font-size: 1px; /* ensure minimum height */
+ height: 10px;
+}
+
+.download .ft .c {
+ height: 10px;
+}
+
+.download .hd {
+ background: transparent url(../images/download.tl.gif) no-repeat 0px 0px;
+}
+
+.download .hd .c {
+ background: transparent url(../images/download.tr.gif) no-repeat right 0px;
+}
+
+.download .bd {
+ background: transparent url(../images/download.ml.gif) repeat-y 0px 0px;
+}
+
+.download .bd .c {
+ background: transparent url(../images/download.mr.gif) repeat-y right 0px;
+}
+
+.download .bd .c .s {
+ margin: 0px 8px 0px 4px;
+ background: #000 url(../images/download.ms.jpg) repeat-x 0px 0px;
+ padding: 1em;
+}
+
+.download .ft {
+ background: transparent url(../images/download.bl.gif) no-repeat 0px 0px;
+}
+
+.download .ft .c {
+ background: transparent url(../images/download.br.gif) no-repeat right 0px;
+}
+
+.download .bd h2 {
+ margin: 0px;
+ text-align: center;
+ border-bottom-width: 0px !important;
+}
+
+.download .bd p {
+ margin: 0px;
+ border: 0px;
+ text-align: left;
+ padding-left: 15px;
+}
+
+.download a {
+ text-decoration: none;
+}
+
+#contentArea {
+ /* margin-right: 15em; */
+ padding: 1em;
+}
+
+#tabs b {
+ border: 1px #DFDEDE solid;
+ padding-left: 1em;
+ padding-right: 1em;
+}
+
+#tabs a {
+ border: 1px #DFDEDE solid;
+ padding-left: 1em;
+ padding-right: 1em;
+ text-decoration: none;
+}
+
+#tabArea {
+ border-top: 1px solid #DFDEDE;
+ padding: 1em;
+}
+
+#searchTypes {
+ text-align: right;
+ font-size: xx-small;
+}
+
+.statusFailed {
+ color: red;
+ font-weight: bold;
+}
+
+/* WebWork validation failures */
+.errorMessage {
+ color: red;
+ font-weight: bold;
+}
+
+.actionMessage {
+ font-weight: bold;
+}
+
+.errorBullet {
+ list-style-image: url( "../images/icon_error_sml.gif" );
+}
+
+.warningBullet {
+ list-style-image: url( "../images/icon_warning_sml.gif" );
+}
+
+.infoBullet {
+ list-style-image: url( "../images/icon_info_sml.gif" );
+}
+
+.artifact-link {
+ font-size: x-small;
+ padding-left: 5em;
+}
+
+.artifact-title {
+
+}
+
+ul.dependencyTree {
+ margin-left: 50px;
+}
+
+ul.dependencyTree span.artifact-link {
+ padding-left: 0px;
+}
+
+.eXtremeTable tr.filter {
+ padding: 1px;
+}
+
+.eXtremeTable .tableRegion,.eXtremeTable .statusBar {
+ width: 100%;
+}
+
+.eXtremeTable .tableHeader {
+ background-color: #F3B455;
+}
+
+.eXtremeTable .tableHeaderSort {
+ background-color: #FFBF5F;
+}
+
+.eXtremeTable .compactToolbar td {
+ white-space: nowrap;
+}
+
+.tools {
+ border-color: gray !important;
+}
+
+.tools .toolHeading {
+ padding: 0px 3px 0px 3px;
+ margin: 0px !important;
+ font-size: 11px !important;
+ background-color: #F3B455 !important;
+}
+
--- /dev/null
+<%--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ --%>
+
+<%response.sendRedirect( request.getContextPath() + "/index.action" );%>
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+// script.aculo.us builder.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
+
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// See scriptaculous.js for full license.
+
+var Builder = {
+ NODEMAP: {
+ AREA: 'map',
+ CAPTION: 'table',
+ COL: 'table',
+ COLGROUP: 'table',
+ LEGEND: 'fieldset',
+ OPTGROUP: 'select',
+ OPTION: 'select',
+ PARAM: 'object',
+ TBODY: 'table',
+ TD: 'table',
+ TFOOT: 'table',
+ TH: 'table',
+ THEAD: 'table',
+ TR: 'table'
+ },
+// note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+// due to a Firefox bug
+ node: function( elementName )
+ {
+ elementName = elementName.toUpperCase();
+
+ // try innerHTML approach
+ var parentTag = this.NODEMAP[elementName] || 'div';
+ var parentElement = document.createElement(parentTag);
+ try
+ { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
+ }
+ catch( e )
+ {
+ }
+ var element = parentElement.firstChild || null;
+
+ // see if browser added wrapping tags
+ if ( element && (element.tagName != elementName) )
+ element = element.getElementsByTagName(elementName)[0];
+
+ // fallback to createElement approach
+ if ( !element ) element = document.createElement(elementName);
+
+ // abort if nothing could be created
+ if ( !element ) return;
+
+ // attributes (or text)
+ if ( arguments[1] )
+ if ( this._isStringOrNumber(arguments[1]) || (arguments[1] instanceof Array) )
+ {
+ this._children(element, arguments[1]);
+ }
+ else
+ {
+ var attrs = this._attributes(arguments[1]);
+ if ( attrs.length )
+ {
+ try
+ { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" + elementName + " " + attrs + "></" + elementName + ">";
+ }
+ catch( e )
+ {
+ }
+ element = parentElement.firstChild || null;
+ // workaround firefox 1.0.X bug
+ if ( !element )
+ {
+ element = document.createElement(elementName);
+ for ( attr in arguments[1] )
+ element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
+ }
+ if ( element.tagName != elementName )
+ element = parentElement.getElementsByTagName(elementName)[0];
+ }
+ }
+
+ // text, or array of children
+ if ( arguments[2] )
+ this._children(element, arguments[2]);
+
+ return element;
+ },
+ _text: function( text )
+ {
+ return document.createTextNode(text);
+ },
+ _attributes: function( attributes )
+ {
+ var attrs = [];
+ for ( attribute in attributes )
+ attrs.push((attribute == 'className' ? 'class' : attribute) + '="' +
+ attributes[attribute].toString().escapeHTML() + '"');
+ return attrs.join(" ");
+ },
+ _children: function( element, children )
+ {
+ if ( typeof children == 'object' )
+ { // array can hold nodes and text
+ children.flatten().each(function( e )
+ {
+ if ( typeof e == 'object' )
+ element.appendChild(e)
+ else
+ if ( Builder._isStringOrNumber(e) )
+ element.appendChild(Builder._text(e));
+ });
+ }
+ else
+ if ( Builder._isStringOrNumber(children) )
+ element.appendChild(Builder._text(children));
+ },
+ _isStringOrNumber: function( param )
+ {
+ return(typeof param == 'string' || typeof param == 'number');
+ },
+ dump: function( scope )
+ {
+ if ( typeof scope != 'object' && typeof scope != 'function' ) scope = window; //global scope
+
+ var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
+ "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
+ "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX " +
+ "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P " +
+ "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD " +
+ "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
+
+ tags.each(function( tag )
+ {
+ scope[tag] = function()
+ {
+ return Builder.node.apply(Builder, [tag].concat($A(arguments)));
+ }
+ });
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+// script.aculo.us controls.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
+
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+// (c) 2005 Jon Tirsen (http://www.tirsen.com)
+// Contributors:
+// Richard Livsey
+// Rahul Bhargava
+// Rob Wills
+//
+// See scriptaculous.js for full license.
+
+// Autocompleter.Base handles all the autocompletion functionality
+// that's independent of the data source for autocompletion. This
+// includes drawing the autocompletion menu, observing keyboard
+// and mouse events, and similar.
+//
+// Specific autocompleters need to provide, at the very least,
+// a getUpdatedChoices function that will be invoked every time
+// the text inside the monitored textbox changes. This method
+// should get the text for which to provide autocompletion by
+// invoking this.getToken(), NOT by directly accessing
+// this.element.value. This is to allow incremental tokenized
+// autocompletion. Specific auto-completion logic (AJAX, etc)
+// belongs in getUpdatedChoices.
+//
+// Tokenized incremental autocompletion is enabled automatically
+// when an autocompleter is instantiated with the 'tokens' option
+// in the options parameter, e.g.:
+// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
+// will incrementally autocomplete with a comma as the token.
+// Additionally, ',' in the above example can be replaced with
+// a token array, e.g. { tokens: [',', '\n'] } which
+// enables autocompletion on multiple tokens. This is most
+// useful when one of the tokens is \n (a newline), as it
+// allows smart autocompletion after linebreaks.
+
+if ( typeof Effect == 'undefined' )
+ throw("controls.js requires including script.aculo.us' effects.js library");
+
+var Autocompleter = {}
+Autocompleter.Base = function()
+{
+};
+Autocompleter.Base.prototype = {
+ baseInitialize: function( element, update, options )
+ {
+ this.element = $(element);
+ this.update = $(update);
+ this.hasFocus = false;
+ this.changed = false;
+ this.active = false;
+ this.index = 0;
+ this.entryCount = 0;
+
+ if ( this.setOptions )
+ this.setOptions(options);
+ else
+ this.options = options || {};
+
+ this.options.paramName = this.options.paramName || this.element.name;
+ this.options.tokens = this.options.tokens || [];
+ this.options.frequency = this.options.frequency || 0.4;
+ this.options.minChars = this.options.minChars || 1;
+ this.options.onShow = this.options.onShow || function( element, update )
+ {
+ if ( !update.style.position || update.style.position == 'absolute' )
+ {
+ update.style.position = 'absolute';
+ Position.clone(element, update, {
+ setHeight: false,
+ offsetTop: element.offsetHeight
+ });
+ }
+ Effect.Appear(update, {duration:0.15});
+ };
+ this.options.onHide = this.options.onHide || function( element, update )
+ {
+ new Effect.Fade(update, {duration:0.15})
+ };
+
+ if ( typeof(this.options.tokens) == 'string' )
+ this.options.tokens = new Array(this.options.tokens);
+
+ this.observer = null;
+
+ this.element.setAttribute('autocomplete', 'off');
+
+ Element.hide(this.update);
+
+ Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
+ Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
+ },
+
+ show: function()
+ {
+ if ( Element.getStyle(this.update, 'display') == 'none' ) this.options.onShow(this.element, this.update);
+ if ( !this.iefix && (navigator.appVersion.indexOf('MSIE') > 0) && (navigator.userAgent.indexOf('Opera') < 0) &&
+ (Element.getStyle(this.update, 'position') == 'absolute') )
+ {
+ new Insertion.After(this.update, '<iframe id="' + this.update.id + '_iefix" ' +
+ 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
+ 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+ this.iefix = $(this.update.id + '_iefix');
+ }
+ if ( this.iefix ) setTimeout(this.fixIEOverlapping.bind(this), 50);
+ },
+
+ fixIEOverlapping: function()
+ {
+ Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
+ this.iefix.style.zIndex = 1;
+ this.update.style.zIndex = 2;
+ Element.show(this.iefix);
+ },
+
+ hide: function()
+ {
+ this.stopIndicator();
+ if ( Element.getStyle(this.update, 'display') != 'none' ) this.options.onHide(this.element, this.update);
+ if ( this.iefix ) Element.hide(this.iefix);
+ },
+
+ startIndicator: function()
+ {
+ if ( this.options.indicator ) Element.show(this.options.indicator);
+ },
+
+ stopIndicator: function()
+ {
+ if ( this.options.indicator ) Element.hide(this.options.indicator);
+ },
+
+ onKeyPress: function( event )
+ {
+ if ( this.active )
+ switch ( event.keyCode )
+ {
+ case Event.KEY_TAB:
+ case Event.KEY_RETURN:
+ this.selectEntry();
+ Event.stop(event);
+ case Event.KEY_ESC:
+ this.hide();
+ this.active = false;
+ Event.stop(event);
+ return;
+ case Event.KEY_LEFT:
+ case Event.KEY_RIGHT:
+ return;
+ case Event.KEY_UP:
+ this.markPrevious();
+ this.render();
+ if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) Event.stop(event);
+ return;
+ case Event.KEY_DOWN:
+ this.markNext();
+ this.render();
+ if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) Event.stop(event);
+ return;
+ }
+ else
+ if ( event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN ||
+ (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0) ) return;
+
+ this.changed = true;
+ this.hasFocus = true;
+
+ if ( this.observer ) clearTimeout(this.observer);
+ this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency * 1000);
+ },
+
+ activate: function()
+ {
+ this.changed = false;
+ this.hasFocus = true;
+ this.getUpdatedChoices();
+ },
+
+ onHover: function( event )
+ {
+ var element = Event.findElement(event, 'LI');
+ if ( this.index != element.autocompleteIndex )
+ {
+ this.index = element.autocompleteIndex;
+ this.render();
+ }
+ Event.stop(event);
+ },
+
+ onClick: function( event )
+ {
+ var element = Event.findElement(event, 'LI');
+ this.index = element.autocompleteIndex;
+ this.selectEntry();
+ this.hide();
+ },
+
+ onBlur: function( event )
+ {
+ // needed to make click events working
+ setTimeout(this.hide.bind(this), 250);
+ this.hasFocus = false;
+ this.active = false;
+ },
+
+ render: function()
+ {
+ if ( this.entryCount > 0 )
+ {
+ for ( var i = 0; i < this.entryCount; i++ )
+ this.index == i ? Element.addClassName(this.getEntry(i), "selected")
+ : Element.removeClassName(this.getEntry(i), "selected");
+
+ if ( this.hasFocus )
+ {
+ this.show();
+ this.active = true;
+ }
+ }
+ else
+ {
+ this.active = false;
+ this.hide();
+ }
+ },
+
+ markPrevious: function()
+ {
+ if ( this.index > 0 ) this.index--
+ else this.index = this.entryCount - 1;
+ this.getEntry(this.index).scrollIntoView(true);
+ },
+
+ markNext: function()
+ {
+ if ( this.index < this.entryCount - 1 ) this.index++
+ else this.index = 0;
+ this.getEntry(this.index).scrollIntoView(false);
+ },
+
+ getEntry: function( index )
+ {
+ return this.update.firstChild.childNodes[index];
+ },
+
+ getCurrentEntry: function()
+ {
+ return this.getEntry(this.index);
+ },
+
+ selectEntry: function()
+ {
+ this.active = false;
+ this.updateElement(this.getCurrentEntry());
+ },
+
+ updateElement: function( selectedElement )
+ {
+ if ( this.options.updateElement )
+ {
+ this.options.updateElement(selectedElement);
+ return;
+ }
+ var value = '';
+ if ( this.options.select )
+ {
+ var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
+ if ( nodes.length > 0 ) value = Element.collectTextNodes(nodes[0], this.options.select);
+ }
+ else
+ value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
+
+ var lastTokenPos = this.findLastToken();
+ if ( lastTokenPos != -1 )
+ {
+ var newValue = this.element.value.substr(0, lastTokenPos + 1);
+ var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
+ if ( whitespace )
+ newValue += whitespace[0];
+ this.element.value = newValue + value;
+ }
+ else
+ {
+ this.element.value = value;
+ }
+ this.element.focus();
+
+ if ( this.options.afterUpdateElement )
+ this.options.afterUpdateElement(this.element, selectedElement);
+ },
+
+ updateChoices: function( choices )
+ {
+ if ( !this.changed && this.hasFocus )
+ {
+ this.update.innerHTML = choices;
+ Element.cleanWhitespace(this.update);
+ Element.cleanWhitespace(this.update.firstChild);
+
+ if ( this.update.firstChild && this.update.firstChild.childNodes )
+ {
+ this.entryCount = this.update.firstChild.childNodes.length;
+ for ( var i = 0; i < this.entryCount; i++ )
+ {
+ var entry = this.getEntry(i);
+ entry.autocompleteIndex = i;
+ this.addObservers(entry);
+ }
+ }
+ else
+ {
+ this.entryCount = 0;
+ }
+
+ this.stopIndicator();
+ this.index = 0;
+
+ if ( this.entryCount == 1 && this.options.autoSelect )
+ {
+ this.selectEntry();
+ this.hide();
+ }
+ else
+ {
+ this.render();
+ }
+ }
+ },
+
+ addObservers: function( element )
+ {
+ Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
+ Event.observe(element, "click", this.onClick.bindAsEventListener(this));
+ },
+
+ onObserverEvent: function()
+ {
+ this.changed = false;
+ if ( this.getToken().length >= this.options.minChars )
+ {
+ this.startIndicator();
+ this.getUpdatedChoices();
+ }
+ else
+ {
+ this.active = false;
+ this.hide();
+ }
+ },
+
+ getToken: function()
+ {
+ var tokenPos = this.findLastToken();
+ if ( tokenPos != -1 )
+ var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/, '').replace(/\s+$/, '');
+ else
+ var ret = this.element.value;
+
+ return /\n/.test(ret) ? '' : ret;
+ },
+
+ findLastToken: function()
+ {
+ var lastTokenPos = -1;
+
+ for ( var i = 0; i < this.options.tokens.length; i++ )
+ {
+ var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
+ if ( thisTokenPos > lastTokenPos )
+ lastTokenPos = thisTokenPos;
+ }
+ return lastTokenPos;
+ }
+}
+
+Ajax.Autocompleter = Class.create();
+Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
+ initialize: function( element, update, url, options )
+ {
+ this.baseInitialize(element, update, options);
+ this.options.asynchronous = true;
+ this.options.onComplete = this.onComplete.bind(this);
+ this.options.defaultParams = this.options.parameters || null;
+ this.url = url;
+ },
+
+ getUpdatedChoices: function()
+ {
+ entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.getToken());
+
+ this.options.parameters = this.options.callback ? this.options.callback(this.element, entry) : entry;
+
+ if ( this.options.defaultParams )
+ this.options.parameters += '&' + this.options.defaultParams;
+
+ new Ajax.Request(this.url, this.options);
+ },
+
+ onComplete: function( request )
+ {
+ this.updateChoices(request.responseText);
+ }
+
+});
+
+// The local array autocompleter. Used when you'd prefer to
+// inject an array of autocompletion options into the page, rather
+// than sending out Ajax queries, which can be quite slow sometimes.
+//
+// The constructor takes four parameters. The first two are, as usual,
+// the id of the monitored textbox, and id of the autocompletion menu.
+// The third is the array you want to autocomplete from, and the fourth
+// is the options block.
+//
+// Extra local autocompletion options:
+// - choices - How many autocompletion choices to offer
+//
+// - partialSearch - If false, the autocompleter will match entered
+// text only at the beginning of strings in the
+// autocomplete array. Defaults to true, which will
+// match text at the beginning of any *word* in the
+// strings in the autocomplete array. If you want to
+// search anywhere in the string, additionally set
+// the option fullSearch to true (default: off).
+//
+// - fullSsearch - Search anywhere in autocomplete array strings.
+//
+// - partialChars - How many characters to enter before triggering
+// a partial match (unlike minChars, which defines
+// how many characters are required to do any match
+// at all). Defaults to 2.
+//
+// - ignoreCase - Whether to ignore case when autocompleting.
+// Defaults to true.
+//
+// It's possible to pass in a custom function as the 'selector'
+// option, if you prefer to write your own autocompletion logic.
+// In that case, the other options above will not apply unless
+// you support them.
+
+Autocompleter.Local = Class.create();
+Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
+ initialize: function( element, update, array, options )
+ {
+ this.baseInitialize(element, update, options);
+ this.options.array = array;
+ },
+
+ getUpdatedChoices: function()
+ {
+ this.updateChoices(this.options.selector(this));
+ },
+
+ setOptions: function( options )
+ {
+ this.options = Object.extend({
+ choices: 10,
+ partialSearch: true,
+ partialChars: 2,
+ ignoreCase: true,
+ fullSearch: false,
+ selector: function( instance )
+ {
+ var ret = [];
+ // Beginning matches
+ var partial = [];
+ // Inside matches
+ var entry = instance.getToken();
+ var count = 0;
+
+ for ( var i = 0; i < instance.options.array.length && ret.length < instance.options.choices; i++ )
+ {
+
+ var elem = instance.options.array[i];
+ var foundPos = instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase())
+ : elem.indexOf(entry);
+
+ while ( foundPos != -1 )
+ {
+ if ( foundPos == 0 && elem.length != entry.length )
+ {
+ ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
+ elem.substr(entry.length) + "</li>");
+ break;
+ }
+ else if ( entry.length >= instance.options.partialChars && instance.options.partialSearch &&
+ foundPos != -1 )
+ {
+ if ( instance.options.fullSearch || /\s/.test(elem.substr(foundPos - 1, 1)) )
+ {
+ partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
+ elem.substr(foundPos, entry.length) + "</strong>" +
+ elem.substr(foundPos + entry.length) + "</li>");
+ break;
+ }
+ }
+
+ foundPos =
+ instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1)
+ : elem.indexOf(entry, foundPos + 1);
+
+ }
+ }
+ if ( partial.length )
+ ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+ return "<ul>" + ret.join('') + "</ul>";
+ }
+ }, options || {});
+ }
+});
+
+// AJAX in-place editor
+//
+// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
+
+// Use this if you notice weird scrolling problems on some browsers,
+// the DOM might be a bit confused when this gets called so do this
+// waits 1 ms (with setTimeout) until it does the activation
+Field.scrollFreeActivate = function( field )
+{
+ setTimeout(function()
+ {
+ Field.activate(field);
+ }, 1);
+}
+
+Ajax.InPlaceEditor = Class.create();
+Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
+Ajax.InPlaceEditor.prototype = {
+ initialize: function( element, url, options )
+ {
+ this.url = url;
+ this.element = $(element);
+
+ this.options = Object.extend({
+ okButton: true,
+ okText: "ok",
+ cancelLink: true,
+ cancelText: "cancel",
+ savingText: "Saving...",
+ clickToEditText: "Click to edit",
+ okText: "ok",
+ rows: 1,
+ onComplete: function( transport, element )
+ {
+ new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
+ },
+ onFailure: function( transport )
+ {
+ alert("Error communicating with the server: " + transport.responseText.stripTags());
+ },
+ callback: function( form )
+ {
+ return Form.serialize(form);
+ },
+ handleLineBreaks: true,
+ loadingText: 'Loading...',
+ savingClassName: 'inplaceeditor-saving',
+ loadingClassName: 'inplaceeditor-loading',
+ formClassName: 'inplaceeditor-form',
+ highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
+ highlightendcolor: "#FFFFFF",
+ externalControl: null,
+ submitOnBlur: false,
+ ajaxOptions: {},
+ evalScripts: false
+ }, options || {});
+
+ if ( !this.options.formId && this.element.id )
+ {
+ this.options.formId = this.element.id + "-inplaceeditor";
+ if ( $(this.options.formId) )
+ {
+ // there's already a form with that name, don't specify an id
+ this.options.formId = null;
+ }
+ }
+
+ if ( this.options.externalControl )
+ {
+ this.options.externalControl = $(this.options.externalControl);
+ }
+
+ this.originalBackground = Element.getStyle(this.element, 'background-color');
+ if ( !this.originalBackground )
+ {
+ this.originalBackground = "transparent";
+ }
+
+ this.element.title = this.options.clickToEditText;
+
+ this.onclickListener = this.enterEditMode.bindAsEventListener(this);
+ this.mouseoverListener = this.enterHover.bindAsEventListener(this);
+ this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
+ Event.observe(this.element, 'click', this.onclickListener);
+ Event.observe(this.element, 'mouseover', this.mouseoverListener);
+ Event.observe(this.element, 'mouseout', this.mouseoutListener);
+ if ( this.options.externalControl )
+ {
+ Event.observe(this.options.externalControl, 'click', this.onclickListener);
+ Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
+ Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
+ }
+ },
+ enterEditMode: function( evt )
+ {
+ if ( this.saving ) return;
+ if ( this.editing ) return;
+ this.editing = true;
+ this.onEnterEditMode();
+ if ( this.options.externalControl )
+ {
+ Element.hide(this.options.externalControl);
+ }
+ Element.hide(this.element);
+ this.createForm();
+ this.element.parentNode.insertBefore(this.form, this.element);
+ if ( !this.options.loadTextURL ) Field.scrollFreeActivate(this.editField);
+ // stop the event to avoid a page refresh in Safari
+ if ( evt )
+ {
+ Event.stop(evt);
+ }
+ return false;
+ },
+ createForm: function()
+ {
+ this.form = document.createElement("form");
+ this.form.id = this.options.formId;
+ Element.addClassName(this.form, this.options.formClassName)
+ this.form.onsubmit = this.onSubmit.bind(this);
+
+ this.createEditField();
+
+ if ( this.options.textarea )
+ {
+ var br = document.createElement("br");
+ this.form.appendChild(br);
+ }
+
+ if ( this.options.okButton )
+ {
+ okButton = document.createElement("input");
+ okButton.type = "submit";
+ okButton.value = this.options.okText;
+ okButton.className = 'editor_ok_button';
+ this.form.appendChild(okButton);
+ }
+
+ if ( this.options.cancelLink )
+ {
+ cancelLink = document.createElement("a");
+ cancelLink.href = "#";
+ cancelLink.appendChild(document.createTextNode(this.options.cancelText));
+ cancelLink.onclick = this.onclickCancel.bind(this);
+ cancelLink.className = 'editor_cancel';
+ this.form.appendChild(cancelLink);
+ }
+ },
+ hasHTMLLineBreaks: function( string )
+ {
+ if ( !this.options.handleLineBreaks ) return false;
+ return string.match(/<br/i) || string.match(/<p>/i);
+ },
+ convertHTMLLineBreaks: function( string )
+ {
+ return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
+ },
+ createEditField: function()
+ {
+ var text;
+ if ( this.options.loadTextURL )
+ {
+ text = this.options.loadingText;
+ }
+ else
+ {
+ text = this.getText();
+ }
+
+ var obj = this;
+
+ if ( this.options.rows == 1 && !this.hasHTMLLineBreaks(text) )
+ {
+ this.options.textarea = false;
+ var textField = document.createElement("input");
+ textField.obj = this;
+ textField.type = "text";
+ textField.name = "value";
+ textField.value = text;
+ textField.style.backgroundColor = this.options.highlightcolor;
+ textField.className = 'editor_field';
+ var size = this.options.size || this.options.cols || 0;
+ if ( size != 0 ) textField.size = size;
+ if ( this.options.submitOnBlur )
+ textField.onblur = this.onSubmit.bind(this);
+ this.editField = textField;
+ }
+ else
+ {
+ this.options.textarea = true;
+ var textArea = document.createElement("textarea");
+ textArea.obj = this;
+ textArea.name = "value";
+ textArea.value = this.convertHTMLLineBreaks(text);
+ textArea.rows = this.options.rows;
+ textArea.cols = this.options.cols || 40;
+ textArea.className = 'editor_field';
+ if ( this.options.submitOnBlur )
+ textArea.onblur = this.onSubmit.bind(this);
+ this.editField = textArea;
+ }
+
+ if ( this.options.loadTextURL )
+ {
+ this.loadExternalText();
+ }
+ this.form.appendChild(this.editField);
+ },
+ getText: function()
+ {
+ return this.element.innerHTML;
+ },
+ loadExternalText: function()
+ {
+ Element.addClassName(this.form, this.options.loadingClassName);
+ this.editField.disabled = true;
+ new Ajax.Request(this.options.loadTextURL, Object.extend({
+ asynchronous: true,
+ onComplete: this.onLoadedExternalText.bind(this)
+ }, this.options.ajaxOptions));
+ },
+ onLoadedExternalText: function( transport )
+ {
+ Element.removeClassName(this.form, this.options.loadingClassName);
+ this.editField.disabled = false;
+ this.editField.value = transport.responseText.stripTags();
+ Field.scrollFreeActivate(this.editField);
+ },
+ onclickCancel: function()
+ {
+ this.onComplete();
+ this.leaveEditMode();
+ return false;
+ },
+ onFailure: function( transport )
+ {
+ this.options.onFailure(transport);
+ if ( this.oldInnerHTML )
+ {
+ this.element.innerHTML = this.oldInnerHTML;
+ this.oldInnerHTML = null;
+ }
+ return false;
+ },
+ onSubmit: function()
+ {
+ // onLoading resets these so we need to save them away for the Ajax call
+ var form = this.form;
+ var value = this.editField.value;
+
+ // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
+ // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
+ // to be displayed indefinitely
+ this.onLoading();
+
+ if ( this.options.evalScripts )
+ {
+ new Ajax.Request(this.url, Object.extend({
+ parameters: this.options.callback(form, value),
+ onComplete: this.onComplete.bind(this),
+ onFailure: this.onFailure.bind(this),
+ asynchronous:true,
+ evalScripts:true
+ }, this.options.ajaxOptions));
+ }
+ else
+ {
+ new Ajax.Updater({ success: this.element,
+ // don't update on failure (this could be an option)
+ failure: null }, this.url, Object.extend({
+ parameters: this.options.callback(form, value),
+ onComplete: this.onComplete.bind(this),
+ onFailure: this.onFailure.bind(this)
+ }, this.options.ajaxOptions));
+ }
+ // stop the event to avoid a page refresh in Safari
+ if ( arguments.length > 1 )
+ {
+ Event.stop(arguments[0]);
+ }
+ return false;
+ },
+ onLoading: function()
+ {
+ this.saving = true;
+ this.removeForm();
+ this.leaveHover();
+ this.showSaving();
+ },
+ showSaving: function()
+ {
+ this.oldInnerHTML = this.element.innerHTML;
+ this.element.innerHTML = this.options.savingText;
+ Element.addClassName(this.element, this.options.savingClassName);
+ this.element.style.backgroundColor = this.originalBackground;
+ Element.show(this.element);
+ },
+ removeForm: function()
+ {
+ if ( this.form )
+ {
+ if ( this.form.parentNode ) Element.remove(this.form);
+ this.form = null;
+ }
+ },
+ enterHover: function()
+ {
+ if ( this.saving ) return;
+ this.element.style.backgroundColor = this.options.highlightcolor;
+ if ( this.effect )
+ {
+ this.effect.cancel();
+ }
+ Element.addClassName(this.element, this.options.hoverClassName)
+ },
+ leaveHover: function()
+ {
+ if ( this.options.backgroundColor )
+ {
+ this.element.style.backgroundColor = this.oldBackground;
+ }
+ Element.removeClassName(this.element, this.options.hoverClassName)
+ if ( this.saving ) return;
+ this.effect = new Effect.Highlight(this.element, {
+ startcolor: this.options.highlightcolor,
+ endcolor: this.options.highlightendcolor,
+ restorecolor: this.originalBackground
+ });
+ },
+ leaveEditMode: function()
+ {
+ Element.removeClassName(this.element, this.options.savingClassName);
+ this.removeForm();
+ this.leaveHover();
+ this.element.style.backgroundColor = this.originalBackground;
+ Element.show(this.element);
+ if ( this.options.externalControl )
+ {
+ Element.show(this.options.externalControl);
+ }
+ this.editing = false;
+ this.saving = false;
+ this.oldInnerHTML = null;
+ this.onLeaveEditMode();
+ },
+ onComplete: function( transport )
+ {
+ this.leaveEditMode();
+ this.options.onComplete.bind(this)(transport, this.element);
+ },
+ onEnterEditMode: function()
+ {
+ },
+ onLeaveEditMode: function()
+ {
+ },
+ dispose: function()
+ {
+ if ( this.oldInnerHTML )
+ {
+ this.element.innerHTML = this.oldInnerHTML;
+ }
+ this.leaveEditMode();
+ Event.stopObserving(this.element, 'click', this.onclickListener);
+ Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
+ Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
+ if ( this.options.externalControl )
+ {
+ Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
+ Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
+ Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
+ }
+ }
+};
+
+Ajax.InPlaceCollectionEditor = Class.create();
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
+ createEditField: function()
+ {
+ if ( !this.cached_selectTag )
+ {
+ var selectTag = document.createElement("select");
+ var collection = this.options.collection || [];
+ var optionTag;
+ collection.each(function( e, i )
+ {
+ optionTag = document.createElement("option");
+ optionTag.value = (e instanceof Array) ? e[0] : e;
+ if ( (typeof this.options.value == 'undefined') &&
+ ((e instanceof Array) ? this.element.innerHTML == e[1] : e ==
+ optionTag.value) ) optionTag.selected =
+ true;
+ if ( this.options.value == optionTag.value ) optionTag.selected = true;
+ optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
+ selectTag.appendChild(optionTag);
+ }.bind(this));
+ this.cached_selectTag = selectTag;
+ }
+
+ this.editField = this.cached_selectTag;
+ if ( this.options.loadTextURL ) this.loadExternalText();
+ this.form.appendChild(this.editField);
+ this.options.callback = function( form, value )
+ {
+ return "value=" + encodeURIComponent(value);
+ }
+ }
+});
+
+// Delayed observer, like Form.Element.Observer,
+// but waits for delay after last key input
+// Ideal for live-search fields
+
+Form.Element.DelayedObserver = Class.create();
+Form.Element.DelayedObserver.prototype = {
+ initialize: function( element, delay, callback )
+ {
+ this.delay = delay || 0.5;
+ this.element = $(element);
+ this.callback = callback;
+ this.timer = null;
+ this.lastValue = $F(this.element);
+ Event.observe(this.element, 'keyup', this.delayedListener.bindAsEventListener(this));
+ },
+ delayedListener: function( event )
+ {
+ if ( this.lastValue == $F(this.element) ) return;
+ if ( this.timer ) clearTimeout(this.timer);
+ this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+ this.lastValue = $F(this.element);
+ },
+ onTimerEvent: function()
+ {
+ this.timer = null;
+ this.callback(this.element, $F(this.element));
+ }
+};
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+// script.aculo.us dragdrop.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
+
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+//
+// See scriptaculous.js for full license.
+
+/*--------------------------------------------------------------------------*/
+
+if ( typeof Effect == 'undefined' )
+ throw("dragdrop.js requires including script.aculo.us' effects.js library");
+
+var Droppables = {
+ drops: [],
+
+ remove: function( element )
+ {
+ this.drops = this.drops.reject(function( d )
+ {
+ return d.element == $(element)
+ });
+ },
+
+ add: function( element )
+ {
+ element = $(element);
+ var options = Object.extend({
+ greedy: true,
+ hoverclass: null,
+ tree: false
+ }, arguments[1] || {});
+
+ // cache containers
+ if ( options.containment )
+ {
+ options._containers = [];
+ var containment = options.containment;
+ if ( (typeof containment == 'object') && (containment.constructor == Array) )
+ {
+ containment.each(function( c )
+ {
+ options._containers.push($(c))
+ });
+ }
+ else
+ {
+ options._containers.push($(containment));
+ }
+ }
+
+ if ( options.accept ) options.accept = [options.accept].flatten();
+
+ Element.makePositioned(element);
+ // fix IE
+ options.element = element;
+
+ this.drops.push(options);
+ },
+
+ findDeepestChild: function( drops )
+ {
+ deepest = drops[0];
+
+ for ( i = 1; i < drops.length; ++i )
+ if ( Element.isParent(drops[i].element, deepest.element) )
+ deepest = drops[i];
+
+ return deepest;
+ },
+
+ isContained: function( element, drop )
+ {
+ var containmentNode;
+ if ( drop.tree )
+ {
+ containmentNode = element.treeNode;
+ }
+ else
+ {
+ containmentNode = element.parentNode;
+ }
+ return drop._containers.detect(function( c )
+ {
+ return containmentNode == c
+ });
+ },
+
+ isAffected: function( point, element, drop )
+ {
+ return (
+ (drop.element != element) && ((!drop._containers) || this.isContained(element, drop)) &&
+ ((!drop.accept) || (Element.classNames(element).detect(function( v )
+ {
+ return drop.accept.include(v)
+ }) )) && Position.within(drop.element, point[0], point[1]) );
+ },
+
+ deactivate: function( drop )
+ {
+ if ( drop.hoverclass )
+ Element.removeClassName(drop.element, drop.hoverclass);
+ this.last_active = null;
+ },
+
+ activate: function( drop )
+ {
+ if ( drop.hoverclass )
+ Element.addClassName(drop.element, drop.hoverclass);
+ this.last_active = drop;
+ },
+
+ show: function( point, element )
+ {
+ if ( !this.drops.length ) return;
+ var affected = [];
+
+ if ( this.last_active ) this.deactivate(this.last_active);
+ this.drops.each(function( drop )
+ {
+ if ( Droppables.isAffected(point, element, drop) )
+ affected.push(drop);
+ });
+
+ if ( affected.length > 0 )
+ {
+ drop = Droppables.findDeepestChild(affected);
+ Position.within(drop.element, point[0], point[1]);
+ if ( drop.onHover )
+ drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
+
+ Droppables.activate(drop);
+ }
+ },
+
+ fire: function( event, element )
+ {
+ if ( !this.last_active ) return;
+ Position.prepare();
+
+ if ( this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active) )
+ if ( this.last_active.onDrop )
+ this.last_active.onDrop(element, this.last_active.element, event);
+ },
+
+ reset: function()
+ {
+ if ( this.last_active )
+ this.deactivate(this.last_active);
+ }
+}
+
+var Draggables = {
+ drags: [],
+ observers: [],
+
+ register: function( draggable )
+ {
+ if ( this.drags.length == 0 )
+ {
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
+ this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
+ this.eventKeypress = this.keyPress.bindAsEventListener(this);
+
+ Event.observe(document, "mouseup", this.eventMouseUp);
+ Event.observe(document, "mousemove", this.eventMouseMove);
+ Event.observe(document, "keypress", this.eventKeypress);
+ }
+ this.drags.push(draggable);
+ },
+
+ unregister: function( draggable )
+ {
+ this.drags = this.drags.reject(function( d )
+ {
+ return d == draggable
+ });
+ if ( this.drags.length == 0 )
+ {
+ Event.stopObserving(document, "mouseup", this.eventMouseUp);
+ Event.stopObserving(document, "mousemove", this.eventMouseMove);
+ Event.stopObserving(document, "keypress", this.eventKeypress);
+ }
+ },
+
+ activate: function( draggable )
+ {
+ if ( draggable.options.delay )
+ {
+ this._timeout = setTimeout(function()
+ {
+ Draggables._timeout = null;
+ window.focus();
+ Draggables.activeDraggable = draggable;
+ }.bind(this), draggable.options.delay);
+ }
+ else
+ {
+ window.focus();
+ // allows keypress events if window isn't currently focused, fails for Safari
+ this.activeDraggable = draggable;
+ }
+ },
+
+ deactivate: function()
+ {
+ this.activeDraggable = null;
+ },
+
+ updateDrag: function( event )
+ {
+ if ( !this.activeDraggable ) return;
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ // Mozilla-based browsers fire successive mousemove events with
+ // the same coordinates, prevent needless redrawing (moz bug?)
+ if ( this._lastPointer && (this._lastPointer.inspect() == pointer.inspect()) ) return;
+ this._lastPointer = pointer;
+
+ this.activeDraggable.updateDrag(event, pointer);
+ },
+
+ endDrag: function( event )
+ {
+ if ( this._timeout )
+ {
+ clearTimeout(this._timeout);
+ this._timeout = null;
+ }
+ if ( !this.activeDraggable ) return;
+ this._lastPointer = null;
+ this.activeDraggable.endDrag(event);
+ this.activeDraggable = null;
+ },
+
+ keyPress: function( event )
+ {
+ if ( this.activeDraggable )
+ this.activeDraggable.keyPress(event);
+ },
+
+ addObserver: function( observer )
+ {
+ this.observers.push(observer);
+ this._cacheObserverCallbacks();
+ },
+
+ removeObserver: function( element )
+ { // element instead of observer fixes mem leaks
+ this.observers = this.observers.reject(function( o )
+ {
+ return o.element == element
+ });
+ this._cacheObserverCallbacks();
+ },
+
+ notify: function( eventName, draggable, event )
+ { // 'onStart', 'onEnd', 'onDrag'
+ if ( this[eventName + 'Count'] > 0 )
+ this.observers.each(function( o )
+ {
+ if ( o[eventName] ) o[eventName](eventName, draggable, event);
+ });
+ if ( draggable.options[eventName] ) draggable.options[eventName](draggable, event);
+ },
+
+ _cacheObserverCallbacks: function()
+ {
+ ['onStart','onEnd','onDrag'].each(function( eventName )
+ {
+ Draggables[eventName + 'Count'] = Draggables.observers.select(function( o )
+ {
+ return o[eventName];
+ }).length;
+ });
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Draggable = Class.create();
+Draggable._dragging = {};
+
+Draggable.prototype = {
+ initialize: function( element )
+ {
+ var defaults = {
+ handle: false,
+ reverteffect: function( element, top_offset, left_offset )
+ {
+ var dur = Math.sqrt(Math.abs(top_offset ^ 2) + Math.abs(left_offset ^ 2)) * 0.02;
+ new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+ queue: {scope:'_draggable', position:'end'}
+ });
+ },
+ endeffect: function( element )
+ {
+ var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
+ queue: {scope:'_draggable', position:'end'},
+ afterFinish: function()
+ {
+ Draggable._dragging[element] = false
+ }
+ });
+ },
+ zindex: 1000,
+ revert: false,
+ scroll: false,
+ scrollSensitivity: 20,
+ scrollSpeed: 15,
+ snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
+ delay: 0
+ };
+
+ if ( arguments[1] && typeof arguments[1].endeffect == 'undefined' )
+ Object.extend(defaults, {
+ starteffect: function( element )
+ {
+ element._opacity = Element.getOpacity(element);
+ Draggable._dragging[element] = true;
+ new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
+ }
+ });
+
+ var options = Object.extend(defaults, arguments[1] || {});
+
+ this.element = $(element);
+
+ if ( options.handle && (typeof options.handle == 'string') )
+ {
+ var h = Element.childrenWithClassName(this.element, options.handle, true);
+ if ( h.length > 0 ) this.handle = h[0];
+ }
+ if ( !this.handle ) this.handle = $(options.handle);
+ if ( !this.handle ) this.handle = this.element;
+
+ if ( options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML )
+ {
+ options.scroll = $(options.scroll);
+ this._isScrollChild = Element.childOf(this.element, options.scroll);
+ }
+
+ Element.makePositioned(this.element);
+ // fix IE
+
+ this.delta = this.currentDelta();
+ this.options = options;
+ this.dragging = false;
+
+ this.eventMouseDown = this.initDrag.bindAsEventListener(this);
+ Event.observe(this.handle, "mousedown", this.eventMouseDown);
+
+ Draggables.register(this);
+ },
+
+ destroy: function()
+ {
+ Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
+ Draggables.unregister(this);
+ },
+
+ currentDelta: function()
+ {
+ return([
+ parseInt(Element.getStyle(this.element, 'left') || '0'),
+ parseInt(Element.getStyle(this.element, 'top') || '0')]);
+ },
+
+ initDrag: function( event )
+ {
+ if ( typeof Draggable._dragging[this.element] != 'undefined' && Draggable._dragging[this.element] ) return;
+ if ( Event.isLeftClick(event) )
+ {
+ // abort on form elements, fixes a Firefox issue
+ var src = Event.element(event);
+ if ( src.tagName && (
+ src.tagName == 'INPUT' || src.tagName == 'SELECT' || src.tagName == 'OPTION' ||
+ src.tagName == 'BUTTON' || src.tagName == 'TEXTAREA') ) return;
+
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var pos = Position.cumulativeOffset(this.element);
+ this.offset = [0,1].map(function( i )
+ {
+ return (pointer[i] - pos[i])
+ });
+
+ Draggables.activate(this);
+ Event.stop(event);
+ }
+ },
+
+ startDrag: function( event )
+ {
+ this.dragging = true;
+
+ if ( this.options.zindex )
+ {
+ this.originalZ = parseInt(Element.getStyle(this.element, 'z-index') || 0);
+ this.element.style.zIndex = this.options.zindex;
+ }
+
+ if ( this.options.ghosting )
+ {
+ this._clone = this.element.cloneNode(true);
+ Position.absolutize(this.element);
+ this.element.parentNode.insertBefore(this._clone, this.element);
+ }
+
+ if ( this.options.scroll )
+ {
+ if ( this.options.scroll == window )
+ {
+ var where = this._getWindowScroll(this.options.scroll);
+ this.originalScrollLeft = where.left;
+ this.originalScrollTop = where.top;
+ }
+ else
+ {
+ this.originalScrollLeft = this.options.scroll.scrollLeft;
+ this.originalScrollTop = this.options.scroll.scrollTop;
+ }
+ }
+
+ Draggables.notify('onStart', this, event);
+
+ if ( this.options.starteffect ) this.options.starteffect(this.element);
+ },
+
+ updateDrag: function( event, pointer )
+ {
+ if ( !this.dragging ) this.startDrag(event);
+ Position.prepare();
+ Droppables.show(pointer, this.element);
+ Draggables.notify('onDrag', this, event);
+
+ this.draw(pointer);
+ if ( this.options.change ) this.options.change(this);
+
+ if ( this.options.scroll )
+ {
+ this.stopScrolling();
+
+ var p;
+ if ( this.options.scroll == window )
+ {
+ with ( this._getWindowScroll(this.options.scroll) )
+ {
+ p = [ left, top, left + width, top + height ];
+ }
+ }
+ else
+ {
+ p = Position.page(this.options.scroll);
+ p[0] += this.options.scroll.scrollLeft;
+ p[1] += this.options.scroll.scrollTop;
+
+ p[0] += (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0);
+ p[1] += (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
+
+ p.push(p[0] + this.options.scroll.offsetWidth);
+ p.push(p[1] + this.options.scroll.offsetHeight);
+ }
+ var speed = [0,0];
+ if ( pointer[0] < (p[0] + this.options.scrollSensitivity) ) speed[0] = pointer[0] - (p[0] +
+ this.options.scrollSensitivity);
+ if ( pointer[1] < (p[1] + this.options.scrollSensitivity) ) speed[1] = pointer[1] - (p[1] +
+ this.options.scrollSensitivity);
+ if ( pointer[0] > (p[2] - this.options.scrollSensitivity) ) speed[0] = pointer[0] - (p[2] -
+ this.options.scrollSensitivity);
+ if ( pointer[1] > (p[3] - this.options.scrollSensitivity) ) speed[1] = pointer[1] - (p[3] -
+ this.options.scrollSensitivity);
+ this.startScrolling(speed);
+ }
+
+ // fix AppleWebKit rendering
+ if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) window.scrollBy(0, 0);
+
+ Event.stop(event);
+ },
+
+ finishDrag: function( event, success )
+ {
+ this.dragging = false;
+
+ if ( this.options.ghosting )
+ {
+ Position.relativize(this.element);
+ Element.remove(this._clone);
+ this._clone = null;
+ }
+
+ if ( success ) Droppables.fire(event, this.element);
+ Draggables.notify('onEnd', this, event);
+
+ var revert = this.options.revert;
+ if ( revert && typeof revert == 'function' ) revert = revert(this.element);
+
+ var d = this.currentDelta();
+ if ( revert && this.options.reverteffect )
+ {
+ this.options.reverteffect(this.element, d[1] - this.delta[1], d[0] - this.delta[0]);
+ }
+ else
+ {
+ this.delta = d;
+ }
+
+ if ( this.options.zindex )
+ this.element.style.zIndex = this.originalZ;
+
+ if ( this.options.endeffect )
+ this.options.endeffect(this.element);
+
+ Draggables.deactivate(this);
+ Droppables.reset();
+ },
+
+ keyPress: function( event )
+ {
+ if ( event.keyCode != Event.KEY_ESC ) return;
+ this.finishDrag(event, false);
+ Event.stop(event);
+ },
+
+ endDrag: function( event )
+ {
+ if ( !this.dragging ) return;
+ this.stopScrolling();
+ this.finishDrag(event, true);
+ Event.stop(event);
+ },
+
+ draw: function( point )
+ {
+ var pos = Position.cumulativeOffset(this.element);
+ if ( this.options.ghosting )
+ {
+ var r = Position.realOffset(this.element);
+ window.status = r.inspect();
+ pos[0] += r[0] - Position.deltaX;
+ pos[1] += r[1] - Position.deltaY;
+ }
+
+ var d = this.currentDelta();
+ pos[0] -= d[0];
+ pos[1] -= d[1];
+
+ if ( this.options.scroll && (this.options.scroll != window && this._isScrollChild) )
+ {
+ pos[0] -= this.options.scroll.scrollLeft - this.originalScrollLeft;
+ pos[1] -= this.options.scroll.scrollTop - this.originalScrollTop;
+ }
+
+ var p = [0,1].map(function( i )
+ {
+ return (point[i] - pos[i] - this.offset[i])
+ }.bind(this));
+
+ if ( this.options.snap )
+ {
+ if ( typeof this.options.snap == 'function' )
+ {
+ p = this.options.snap(p[0], p[1], this);
+ }
+ else
+ {
+ if ( this.options.snap instanceof Array )
+ {
+ p = p.map(function( v, i )
+ {
+ return Math.round(v / this.options.snap[i]) * this.options.snap[i]
+ }.bind(this))
+ }
+ else
+ {
+ p = p.map(function( v )
+ {
+ return Math.round(v / this.options.snap) * this.options.snap
+ }.bind(this))
+ }
+ }
+ }
+
+ var style = this.element.style;
+ if ( (!this.options.constraint) || (this.options.constraint == 'horizontal') )
+ style.left = p[0] + "px";
+ if ( (!this.options.constraint) || (this.options.constraint == 'vertical') )
+ style.top = p[1] + "px";
+
+ if ( style.visibility == "hidden" ) style.visibility = ""; // fix gecko rendering
+ },
+
+ stopScrolling: function()
+ {
+ if ( this.scrollInterval )
+ {
+ clearInterval(this.scrollInterval);
+ this.scrollInterval = null;
+ Draggables._lastScrollPointer = null;
+ }
+ },
+
+ startScrolling: function( speed )
+ {
+ if ( !(speed[0] || speed[1]) ) return;
+ this.scrollSpeed = [speed[0] * this.options.scrollSpeed,speed[1] * this.options.scrollSpeed];
+ this.lastScrolled = new Date();
+ this.scrollInterval = setInterval(this.scroll.bind(this), 10);
+ },
+
+ scroll: function()
+ {
+ var current = new Date();
+ var delta = current - this.lastScrolled;
+ this.lastScrolled = current;
+ if ( this.options.scroll == window )
+ {
+ with ( this._getWindowScroll(this.options.scroll) )
+ {
+ if ( this.scrollSpeed[0] || this.scrollSpeed[1] )
+ {
+ var d = delta / 1000;
+ this.options.scroll.scrollTo(left + d * this.scrollSpeed[0], top + d * this.scrollSpeed[1]);
+ }
+ }
+ }
+ else
+ {
+ this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
+ this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
+ }
+
+ Position.prepare();
+ Droppables.show(Draggables._lastPointer, this.element);
+ Draggables.notify('onDrag', this);
+ if ( this._isScrollChild )
+ {
+ Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
+ Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
+ Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
+ if ( Draggables._lastScrollPointer[0] < 0 )
+ Draggables._lastScrollPointer[0] = 0;
+ if ( Draggables._lastScrollPointer[1] < 0 )
+ Draggables._lastScrollPointer[1] = 0;
+ this.draw(Draggables._lastScrollPointer);
+ }
+
+ if ( this.options.change ) this.options.change(this);
+ },
+
+ _getWindowScroll: function( w )
+ {
+ var T, L, W, H;
+ with ( w.document )
+ {
+ if ( w.document.documentElement && documentElement.scrollTop )
+ {
+ T = documentElement.scrollTop;
+ L = documentElement.scrollLeft;
+ }
+ else if ( w.document.body )
+ {
+ T = body.scrollTop;
+ L = body.scrollLeft;
+ }
+ if ( w.innerWidth )
+ {
+ W = w.innerWidth;
+ H = w.innerHeight;
+ }
+ else if ( w.document.documentElement && documentElement.clientWidth )
+ {
+ W = documentElement.clientWidth;
+ H = documentElement.clientHeight;
+ }
+ else
+ {
+ W = body.offsetWidth;
+ H = body.offsetHeight
+ }
+ }
+ return { top: T, left: L, width: W, height: H };
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var SortableObserver = Class.create();
+SortableObserver.prototype = {
+ initialize: function( element, observer )
+ {
+ this.element = $(element);
+ this.observer = observer;
+ this.lastValue = Sortable.serialize(this.element);
+ },
+
+ onStart: function()
+ {
+ this.lastValue = Sortable.serialize(this.element);
+ },
+
+ onEnd: function()
+ {
+ Sortable.unmark();
+ if ( this.lastValue != Sortable.serialize(this.element) )
+ this.observer(this.element)
+ }
+}
+
+var Sortable = {
+ SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
+
+ sortables: {},
+
+ _findRootElement: function( element )
+ {
+ while ( element.tagName != "BODY" )
+ {
+ if ( element.id && Sortable.sortables[element.id] ) return element;
+ element = element.parentNode;
+ }
+ },
+
+ options: function( element )
+ {
+ element = Sortable._findRootElement($(element));
+ if ( !element ) return;
+ return Sortable.sortables[element.id];
+ },
+
+ destroy: function( element )
+ {
+ var s = Sortable.options(element);
+
+ if ( s )
+ {
+ Draggables.removeObserver(s.element);
+ s.droppables.each(function( d )
+ {
+ Droppables.remove(d)
+ });
+ s.draggables.invoke('destroy');
+
+ delete Sortable.sortables[s.element.id];
+ }
+ },
+
+ create: function( element )
+ {
+ element = $(element);
+ var options = Object.extend({
+ element: element,
+ tag: 'li', // assumes li children, override with tag: 'tagname'
+ dropOnEmpty: false,
+ tree: false,
+ treeTag: 'ul',
+ overlap: 'vertical', // one of 'vertical', 'horizontal'
+ constraint: 'vertical', // one of 'vertical', 'horizontal', false
+ containment: element, // also takes array of elements (or id's); or false
+ handle: false, // or a CSS class
+ only: false,
+ delay: 0,
+ hoverclass: null,
+ ghosting: false,
+ scroll: false,
+ scrollSensitivity: 20,
+ scrollSpeed: 15,
+ format: this.SERIALIZE_RULE,
+ onChange: Prototype.emptyFunction,
+ onUpdate: Prototype.emptyFunction
+ }, arguments[1] || {});
+
+ // clear any old sortable with same element
+ this.destroy(element);
+
+ // build options for the draggables
+ var options_for_draggable = {
+ revert: true,
+ scroll: options.scroll,
+ scrollSpeed: options.scrollSpeed,
+ scrollSensitivity: options.scrollSensitivity,
+ delay: options.delay,
+ ghosting: options.ghosting,
+ constraint: options.constraint,
+ handle: options.handle };
+
+ if ( options.starteffect )
+ options_for_draggable.starteffect = options.starteffect;
+
+ if ( options.reverteffect )
+ options_for_draggable.reverteffect = options.reverteffect;
+ else
+ if ( options.ghosting ) options_for_draggable.reverteffect = function( element )
+ {
+ element.style.top = 0;
+ element.style.left = 0;
+ };
+
+ if ( options.endeffect )
+ options_for_draggable.endeffect = options.endeffect;
+
+ if ( options.zindex )
+ options_for_draggable.zindex = options.zindex;
+
+ // build options for the droppables
+ var options_for_droppable = {
+ overlap: options.overlap,
+ containment: options.containment,
+ tree: options.tree,
+ hoverclass: options.hoverclass,
+ onHover: Sortable.onHover
+ //greedy: !options.dropOnEmpty
+ }
+
+ var options_for_tree = {
+ onHover: Sortable.onEmptyHover,
+ overlap: options.overlap,
+ containment: options.containment,
+ hoverclass: options.hoverclass
+ }
+
+ // fix for gecko engine
+ Element.cleanWhitespace(element);
+
+ options.draggables = [];
+ options.droppables = [];
+
+ // drop on empty handling
+ if ( options.dropOnEmpty || options.tree )
+ {
+ Droppables.add(element, options_for_tree);
+ options.droppables.push(element);
+ }
+
+ (this.findElements(element, options) || []).each(function( e )
+ {
+ // handles are per-draggable
+ var handle = options.handle ? Element.childrenWithClassName(e, options.handle)[0] : e;
+ options.draggables.push(new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
+ Droppables.add(e, options_for_droppable);
+ if ( options.tree ) e.treeNode = element;
+ options.droppables.push(e);
+ });
+
+ if ( options.tree )
+ {
+ (Sortable.findTreeElements(element, options) || []).each(function( e )
+ {
+ Droppables.add(e, options_for_tree);
+ e.treeNode = element;
+ options.droppables.push(e);
+ });
+ }
+
+ // keep reference
+ this.sortables[element.id] = options;
+
+ // for onupdate
+ Draggables.addObserver(new SortableObserver(element, options.onUpdate));
+
+ },
+
+// return all suitable-for-sortable elements in a guaranteed order
+ findElements: function( element, options )
+ {
+ return Element.findChildren(element, options.only, options.tree ? true : false, options.tag);
+ },
+
+ findTreeElements: function( element, options )
+ {
+ return Element.findChildren(element, options.only, options.tree ? true : false, options.treeTag);
+ },
+
+ onHover: function( element, dropon, overlap )
+ {
+ if ( Element.isParent(dropon, element) ) return;
+
+ if ( overlap > .33 && overlap < .66 && Sortable.options(dropon).tree )
+ {
+ return;
+ }
+ else if ( overlap > 0.5 )
+ {
+ Sortable.mark(dropon, 'before');
+ if ( dropon.previousSibling != element )
+ {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = "hidden";
+ // fix gecko rendering
+ dropon.parentNode.insertBefore(element, dropon);
+ if ( dropon.parentNode != oldParentNode )
+ Sortable.options(oldParentNode).onChange(element);
+ Sortable.options(dropon.parentNode).onChange(element);
+ }
+ }
+ else
+ {
+ Sortable.mark(dropon, 'after');
+ var nextElement = dropon.nextSibling || null;
+ if ( nextElement != element )
+ {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = "hidden";
+ // fix gecko rendering
+ dropon.parentNode.insertBefore(element, nextElement);
+ if ( dropon.parentNode != oldParentNode )
+ Sortable.options(oldParentNode).onChange(element);
+ Sortable.options(dropon.parentNode).onChange(element);
+ }
+ }
+ },
+
+ onEmptyHover: function( element, dropon, overlap )
+ {
+ var oldParentNode = element.parentNode;
+ var droponOptions = Sortable.options(dropon);
+
+ if ( !Element.isParent(dropon, element) )
+ {
+ var index;
+
+ var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
+ var child = null;
+
+ if ( children )
+ {
+ var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
+
+ for ( index = 0; index < children.length; index += 1 )
+ {
+ if ( offset - Element.offsetSize(children[index], droponOptions.overlap) >= 0 )
+ {
+ offset -= Element.offsetSize(children[index], droponOptions.overlap);
+ }
+ else if ( offset - (Element.offsetSize(children[index], droponOptions.overlap) / 2) >= 0 )
+ {
+ child = index + 1 < children.length ? children[index + 1] : null;
+ break;
+ }
+ else
+ {
+ child = children[index];
+ break;
+ }
+ }
+ }
+
+ dropon.insertBefore(element, child);
+
+ Sortable.options(oldParentNode).onChange(element);
+ droponOptions.onChange(element);
+ }
+ },
+
+ unmark: function()
+ {
+ if ( Sortable._marker ) Element.hide(Sortable._marker);
+ },
+
+ mark: function( dropon, position )
+ {
+ // mark on ghosting only
+ var sortable = Sortable.options(dropon.parentNode);
+ if ( sortable && !sortable.ghosting ) return;
+
+ if ( !Sortable._marker )
+ {
+ Sortable._marker = $('dropmarker') || document.createElement('DIV');
+ Element.hide(Sortable._marker);
+ Element.addClassName(Sortable._marker, 'dropmarker');
+ Sortable._marker.style.position = 'absolute';
+ document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
+ }
+ var offsets = Position.cumulativeOffset(dropon);
+ Sortable._marker.style.left = offsets[0] + 'px';
+ Sortable._marker.style.top = offsets[1] + 'px';
+
+ if ( position == 'after' )
+ if ( sortable.overlap == 'horizontal' )
+ Sortable._marker.style.left = (offsets[0] + dropon.clientWidth) + 'px';
+ else
+ Sortable._marker.style.top = (offsets[1] + dropon.clientHeight) + 'px';
+
+ Element.show(Sortable._marker);
+ },
+
+ _tree: function( element, options, parent )
+ {
+ var children = Sortable.findElements(element, options) || [];
+
+ for ( var i = 0; i < children.length; ++i )
+ {
+ var match = children[i].id.match(options.format);
+
+ if ( !match ) continue;
+
+ var child = {
+ id: encodeURIComponent(match ? match[1] : null),
+ element: element,
+ parent: parent,
+ children: new Array,
+ position: parent.children.length,
+ container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase())
+ }
+
+ /* Get the element containing the children and recurse over it */
+ if ( child.container )
+ this._tree(child.container, options, child)
+
+ parent.children.push(child);
+ }
+
+ return parent;
+ },
+
+/* Finds the first element of the given tag type within a parent element.
+Used for finding the first LI[ST] within a L[IST]I[TEM].*/
+ _findChildrenElement: function ( element, containerTag )
+ {
+ if ( element && element.hasChildNodes )
+ for ( var i = 0; i < element.childNodes.length; ++i )
+ if ( element.childNodes[i].tagName == containerTag )
+ return element.childNodes[i];
+
+ return null;
+ },
+
+ tree: function( element )
+ {
+ element = $(element);
+ var sortableOptions = this.options(element);
+ var options = Object.extend({
+ tag: sortableOptions.tag,
+ treeTag: sortableOptions.treeTag,
+ only: sortableOptions.only,
+ name: element.id,
+ format: sortableOptions.format
+ }, arguments[1] || {});
+
+ var root = {
+ id: null,
+ parent: null,
+ children: new Array,
+ container: element,
+ position: 0
+ }
+
+ return Sortable._tree(element, options, root);
+ },
+
+/* Construct a [i] index for a particular node */
+ _constructIndex: function( node )
+ {
+ var index = '';
+ do {
+ if ( node.id ) index = '[' + node.position + ']' + index;
+ }
+ while ( (node = node.parent) != null );
+ return index;
+ },
+
+ sequence: function( element )
+ {
+ element = $(element);
+ var options = Object.extend(this.options(element), arguments[1] || {});
+
+ return $(this.findElements(element, options) || []).map(function( item )
+ {
+ return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
+ });
+ },
+
+ setSequence: function( element, new_sequence )
+ {
+ element = $(element);
+ var options = Object.extend(this.options(element), arguments[2] || {});
+
+ var nodeMap = {};
+ this.findElements(element, options).each(function( n )
+ {
+ if ( n.id.match(options.format) )
+ nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
+ n.parentNode.removeChild(n);
+ });
+
+ new_sequence.each(function( ident )
+ {
+ var n = nodeMap[ident];
+ if ( n )
+ {
+ n[1].appendChild(n[0]);
+ delete nodeMap[ident];
+ }
+ });
+ },
+
+ serialize: function( element )
+ {
+ element = $(element);
+ var options = Object.extend(Sortable.options(element), arguments[1] || {});
+ var name = encodeURIComponent((arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
+
+ if ( options.tree )
+ {
+ return Sortable.tree(element, arguments[1]).children.map(function ( item )
+ {
+ return [name + Sortable._constructIndex(item) + "[id]=" +
+ encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
+ }).flatten().join('&');
+ }
+ else
+ {
+ return Sortable.sequence(element, arguments[1]).map(function( item )
+ {
+ return name + "[]=" + encodeURIComponent(item);
+ }).join('&');
+ }
+ }
+}
+
+/* Returns true if child is contained within element */
+Element.isParent = function( child, element )
+{
+ if ( !child.parentNode || child == element ) return false;
+
+ if ( child.parentNode == element ) return true;
+
+ return Element.isParent(child.parentNode, element);
+}
+
+Element.findChildren = function( element, only, recursive, tagName )
+{
+ if ( !element.hasChildNodes() ) return null;
+ tagName = tagName.toUpperCase();
+ if ( only ) only = [only].flatten();
+ var elements = [];
+ $A(element.childNodes).each(function( e )
+ {
+ if ( e.tagName && e.tagName.toUpperCase() == tagName && (!only || (Element.classNames(e).detect(function( v )
+ {
+ return only.include(v)
+ }))) )
+ elements.push(e);
+ if ( recursive )
+ {
+ var grandchildren = Element.findChildren(e, only, recursive, tagName);
+ if ( grandchildren ) elements.push(grandchildren);
+ }
+ });
+
+ return (elements.length > 0 ? elements.flatten() : []);
+}
+
+Element.offsetSize = function ( element, type )
+{
+ if ( type == 'vertical' || type == 'height' )
+ return element.offsetHeight;
+ else
+ return element.offsetWidth;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+// script.aculo.us effects.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
+
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+// Justin Palmer (http://encytemedia.com/)
+// Mark Pilgrim (http://diveintomark.org/)
+// Martin Bialasinki
+//
+// See scriptaculous.js for full license.
+
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function()
+{
+ var color = '#';
+ if ( this.slice(0, 4) == 'rgb(' )
+ {
+ var cols = this.slice(4, this.length - 1).split(',');
+ var i = 0;
+ do {
+ color += parseInt(cols[i]).toColorPart()
+ }
+ while ( ++i < 3 );
+ }
+ else
+ {
+ if ( this.slice(0, 1) == '#' )
+ {
+ if ( this.length == 4 ) for ( var i = 1; i < 4; i++ ) color +=
+ (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if ( this.length == 7 ) color = this.toLowerCase();
+ }
+ }
+ return(color.length == 7 ? color : (arguments[0] || this));
+}
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function( element )
+{
+ return $A($(element).childNodes).collect(function( node )
+ {
+ return (node.nodeType == 3 ? node.nodeValue : (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+ }).flatten().join('');
+}
+
+Element.collectTextNodesIgnoreClass = function( element, className )
+{
+ return $A($(element).childNodes).collect(function( node )
+ {
+ return (node.nodeType == 3 ? node.nodeValue : ((node.hasChildNodes() && !Element.hasClassName(node, className))
+ ? Element.collectTextNodesIgnoreClass(node, className) : ''));
+ }).flatten().join('');
+}
+
+Element.setContentZoom = function( element, percent )
+{
+ element = $(element);
+ Element.setStyle(element, {fontSize: (percent / 100) + 'em'});
+ if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) window.scrollBy(0, 0);
+}
+
+Element.getOpacity = function( element )
+{
+ var opacity;
+ if ( opacity = Element.getStyle(element, 'opacity') )
+ return parseFloat(opacity);
+ if ( opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/) )
+ if ( opacity[1] ) return parseFloat(opacity[1]) / 100;
+ return 1.0;
+}
+
+Element.setOpacity = function( element, value )
+{
+ element = $(element);
+ if ( value == 1 )
+ {
+ Element.setStyle(element, { opacity:
+ (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999
+ : 1.0 });
+ if ( /MSIE/.test(navigator.userAgent) && !window.opera )
+ Element.setStyle(element, {filter: Element.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '')});
+ }
+ else
+ {
+ if ( value < 0.00001 ) value = 0;
+ Element.setStyle(element, {opacity: value});
+ if ( /MSIE/.test(navigator.userAgent) && !window.opera )
+ Element.setStyle(element, { filter: Element.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '') +
+ 'alpha(opacity=' + value * 100 + ')' });
+ }
+}
+
+Element.getInlineOpacity = function( element )
+{
+ return $(element).style.opacity || '';
+}
+
+Element.childrenWithClassName = function( element, className, findFirst )
+{
+ var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
+ var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select'](function( c )
+ {
+ return (c.className && c.className.match(classNameRegExp));
+ });
+ if ( !results ) results = [];
+ return results;
+}
+
+Element.forceRerendering = function( element )
+{
+ try
+ {
+ element = $(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ }
+ catch( e )
+ {
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Array.prototype.call = function()
+{
+ var args = arguments;
+ this.each(function( f )
+ {
+ f.apply(this, args)
+ });
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+ _elementDoesNotExistError: {
+ name: 'ElementDoesNotExistError',
+ message: 'The specified DOM element does not exist, but is required for this effect to operate'
+ },
+ tagifyText: function( element )
+ {
+ if ( typeof Builder == 'undefined' )
+ throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+
+ var tagifyStyle = 'position:relative';
+ if ( /MSIE/.test(navigator.userAgent) && !window.opera ) tagifyStyle += ';zoom:1';
+ element = $(element);
+ $A(element.childNodes).each(function( child )
+ {
+ if ( child.nodeType == 3 )
+ {
+ child.nodeValue.toArray().each(function( character )
+ {
+ element.insertBefore(Builder.node('span', {style: tagifyStyle}, character == ' '
+ ? String.fromCharCode(160) : character), child);
+ });
+ Element.remove(child);
+ }
+ });
+ },
+ multiple: function( element, effect )
+ {
+ var elements;
+ if ( ((typeof element == 'object') || (typeof element == 'function')) && (element.length) )
+ elements = element;
+ else
+ elements = $(element).childNodes;
+
+ var options = Object.extend({
+ speed: 0.1,
+ delay: 0.0
+ }, arguments[2] || {});
+ var masterDelay = options.delay;
+
+ $A(elements).each(function( element, index )
+ {
+ new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+ });
+ },
+ PAIRS: {
+ 'slide': ['SlideDown','SlideUp'],
+ 'blind': ['BlindDown','BlindUp'],
+ 'appear': ['Appear','Fade']
+ },
+ toggle: function( element, effect )
+ {
+ element = $(element);
+ effect = (effect || 'appear').toLowerCase();
+ var options = Object.extend({
+ queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+ }, arguments[2] || {});
+ Effect[element.visible() ? Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }
+};
+
+var Effect2 = Effect;
+// deprecated
+
+/* ------------- transitions ------------- */
+
+Effect.Transitions = {}
+
+Effect.Transitions.linear = Prototype.K;
+
+Effect.Transitions.sinoidal = function( pos )
+{
+ return (-Math.cos(pos * Math.PI) / 2) + 0.5;
+}
+Effect.Transitions.reverse = function( pos )
+{
+ return 1 - pos;
+}
+Effect.Transitions.flicker = function( pos )
+{
+ return ((-Math.cos(pos * Math.PI) / 4) + 0.75) + Math.random() / 4;
+}
+Effect.Transitions.wobble = function( pos )
+{
+ return (-Math.cos(pos * Math.PI * (9 * pos)) / 2) + 0.5;
+}
+Effect.Transitions.pulse = function( pos )
+{
+ return (Math.floor(pos * 10) % 2 == 0 ? (pos * 10 - Math.floor(pos * 10)) : 1 - (pos * 10 - Math.floor(pos * 10)));
+}
+Effect.Transitions.none = function( pos )
+{
+ return 0;
+}
+Effect.Transitions.full = function( pos )
+{
+ return 1;
+}
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create();
+Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
+ initialize: function()
+ {
+ this.effects = [];
+ this.interval = null;
+ },
+ _each: function( iterator )
+ {
+ this.effects._each(iterator);
+ },
+ add: function( effect )
+ {
+ var timestamp = new Date().getTime();
+
+ var position = (typeof effect.options.queue == 'string') ? effect.options.queue : effect.options.queue.position;
+
+ switch ( position )
+ {
+ case 'front':
+ // move unstarted effects after this effect
+ this.effects.findAll(function( e )
+ {
+ return e.state == 'idle'
+ }).each(function( e )
+ {
+ e.startOn += effect.finishOn;
+ e.finishOn += effect.finishOn;
+ });
+ break;
+ case 'end':
+ // start effect after last queued effect has finished
+ timestamp = this.effects.pluck('finishOn').max() || timestamp;
+ break;
+ }
+
+ effect.startOn += timestamp;
+ effect.finishOn += timestamp;
+
+ if ( !effect.options.queue.limit || (this.effects.length < effect.options.queue.limit) )
+ this.effects.push(effect);
+
+ if ( !this.interval )
+ this.interval = setInterval(this.loop.bind(this), 40);
+ },
+ remove: function( effect )
+ {
+ this.effects = this.effects.reject(function( e )
+ {
+ return e == effect
+ });
+ if ( this.effects.length == 0 )
+ {
+ clearInterval(this.interval);
+ this.interval = null;
+ }
+ },
+ loop: function()
+ {
+ var timePos = new Date().getTime();
+ this.effects.invoke('loop', timePos);
+ }
+});
+
+Effect.Queues = {
+ instances: $H(),
+ get: function( queueName )
+ {
+ if ( typeof queueName != 'string' ) return queueName;
+
+ if ( !this.instances[queueName] )
+ this.instances[queueName] = new Effect.ScopedQueue();
+
+ return this.instances[queueName];
+ }
+}
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.DefaultOptions = {
+ transition: Effect.Transitions.sinoidal,
+ duration: 1.0, // seconds
+ fps: 25.0, // max. 25fps due to Effect.Queue implementation
+ sync: false, // true for combining
+ from: 0.0,
+ to: 1.0,
+ delay: 0.0,
+ queue: 'parallel'
+}
+
+Effect.Base = function()
+{
+};
+Effect.Base.prototype = {
+ position: null,
+ start: function( options )
+ {
+ this.options = Object.extend(Object.extend({}, Effect.DefaultOptions), options || {});
+ this.currentFrame = 0;
+ this.state = 'idle';
+ this.startOn = this.options.delay * 1000;
+ this.finishOn = this.startOn + (this.options.duration * 1000);
+ this.event('beforeStart');
+ if ( !this.options.sync )
+ Effect.Queues.get(typeof this.options.queue == 'string' ? 'global' : this.options.queue.scope).add(this);
+ },
+ loop: function( timePos )
+ {
+ if ( timePos >= this.startOn )
+ {
+ if ( timePos >= this.finishOn )
+ {
+ this.render(1.0);
+ this.cancel();
+ this.event('beforeFinish');
+ if ( this.finish ) this.finish();
+ this.event('afterFinish');
+ return;
+ }
+ var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
+ var frame = Math.round(pos * this.options.fps * this.options.duration);
+ if ( frame > this.currentFrame )
+ {
+ this.render(pos);
+ this.currentFrame = frame;
+ }
+ }
+ },
+ render: function( pos )
+ {
+ if ( this.state == 'idle' )
+ {
+ this.state = 'running';
+ this.event('beforeSetup');
+ if ( this.setup ) this.setup();
+ this.event('afterSetup');
+ }
+ if ( this.state == 'running' )
+ {
+ if ( this.options.transition ) pos = this.options.transition(pos);
+ pos *= (this.options.to - this.options.from);
+ pos += this.options.from;
+ this.position = pos;
+ this.event('beforeUpdate');
+ if ( this.update ) this.update(pos);
+ this.event('afterUpdate');
+ }
+ },
+ cancel: function()
+ {
+ if ( !this.options.sync )
+ Effect.Queues.get(typeof this.options.queue == 'string' ? 'global' : this.options.queue.scope).remove(this);
+ this.state = 'finished';
+ },
+ event: function( eventName )
+ {
+ if ( this.options[eventName + 'Internal'] ) this.options[eventName + 'Internal'](this);
+ if ( this.options[eventName] ) this.options[eventName](this);
+ },
+ inspect: function()
+ {
+ return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
+ }
+}
+
+Effect.Parallel = Class.create();
+Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
+ initialize: function( effects )
+ {
+ this.effects = effects || [];
+ this.start(arguments[1]);
+ },
+ update: function( position )
+ {
+ this.effects.invoke('render', position);
+ },
+ finish: function( position )
+ {
+ this.effects.each(function( effect )
+ {
+ effect.render(1.0);
+ effect.cancel();
+ effect.event('beforeFinish');
+ if ( effect.finish ) effect.finish(position);
+ effect.event('afterFinish');
+ });
+ }
+});
+
+Effect.Opacity = Class.create();
+Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
+ initialize: function( element )
+ {
+ this.element = $(element);
+ if ( !this.element ) throw(Effect._elementDoesNotExistError);
+ // make this work on IE on elements without 'layout'
+ if ( /MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout) )
+ this.element.setStyle({zoom: 1});
+ var options = Object.extend({
+ from: this.element.getOpacity() || 0.0,
+ to: 1.0
+ }, arguments[1] || {});
+ this.start(options);
+ },
+ update: function( position )
+ {
+ this.element.setOpacity(position);
+ }
+});
+
+Effect.Move = Class.create();
+Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
+ initialize: function( element )
+ {
+ this.element = $(element);
+ if ( !this.element ) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ x: 0,
+ y: 0,
+ mode: 'relative'
+ }, arguments[1] || {});
+ this.start(options);
+ },
+ setup: function()
+ {
+ // Bug in Opera: Opera returns the "real" position of a static element or
+ // relative element that does not have top/left explicitly set.
+ // ==> Always set top and left for position relative elements in your stylesheets
+ // (to 0 if you do not need them)
+ this.element.makePositioned();
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+ this.originalTop = parseFloat(this.element.getStyle('top') || '0');
+ if ( this.options.mode == 'absolute' )
+ {
+ // absolute movement, so we need to calc deltaX and deltaY
+ this.options.x = this.options.x - this.originalLeft;
+ this.options.y = this.options.y - this.originalTop;
+ }
+ },
+ update: function( position )
+ {
+ this.element.setStyle({
+ left: Math.round(this.options.x * position + this.originalLeft) + 'px',
+ top: Math.round(this.options.y * position + this.originalTop) + 'px'
+ });
+ }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function( element, toTop, toLeft )
+{
+ return new Effect.Move(element, Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
+};
+
+Effect.Scale = Class.create();
+Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
+ initialize: function( element, percent )
+ {
+ this.element = $(element);
+ if ( !this.element ) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ scaleX: true,
+ scaleY: true,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleMode: 'box', // 'box' or 'contents' or {} with provided values
+ scaleFrom: 100.0,
+ scaleTo: percent
+ }, arguments[2] || {});
+ this.start(options);
+ },
+ setup: function()
+ {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = this.element.getStyle('position');
+
+ this.originalStyle = {};
+ ['top','left','width','height','fontSize'].each(function( k )
+ {
+ this.originalStyle[k] = this.element.style[k];
+ }.bind(this));
+
+ this.originalTop = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = this.element.getStyle('font-size') || '100%';
+ ['em','px','%','pt'].each(function( fontSizeType )
+ {
+ if ( fontSize.indexOf(fontSizeType) > 0 )
+ {
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
+ }
+ }.bind(this));
+
+ this.factor = (this.options.scaleTo - this.options.scaleFrom) / 100;
+
+ this.dims = null;
+ if ( this.options.scaleMode == 'box' )
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ if ( /^content/.test(this.options.scaleMode) )
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+ if ( !this.dims )
+ this.dims = [this.options.scaleMode.originalHeight,
+ this.options.scaleMode.originalWidth];
+ },
+ update: function( position )
+ {
+ var currentScale = (this.options.scaleFrom / 100.0) + (this.factor * position);
+ if ( this.options.scaleContent && this.fontSize )
+ this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+ this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+ },
+ finish: function( position )
+ {
+ if ( this.restoreAfterFinish ) this.element.setStyle(this.originalStyle);
+ },
+ setDimensions: function( height, width )
+ {
+ var d = {};
+ if ( this.options.scaleX ) d.width = Math.round(width) + 'px';
+ if ( this.options.scaleY ) d.height = Math.round(height) + 'px';
+ if ( this.options.scaleFromCenter )
+ {
+ var topd = (height - this.dims[0]) / 2;
+ var leftd = (width - this.dims[1]) / 2;
+ if ( this.elementPositioning == 'absolute' )
+ {
+ if ( this.options.scaleY ) d.top = this.originalTop - topd + 'px';
+ if ( this.options.scaleX ) d.left = this.originalLeft - leftd + 'px';
+ }
+ else
+ {
+ if ( this.options.scaleY ) d.top = -topd + 'px';
+ if ( this.options.scaleX ) d.left = -leftd + 'px';
+ }
+ }
+ this.element.setStyle(d);
+ }
+});
+
+Effect.Highlight = Class.create();
+Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
+ initialize: function( element )
+ {
+ this.element = $(element);
+ if ( !this.element ) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
+ this.start(options);
+ },
+ setup: function()
+ {
+ // Prevent executing on elements not in the layout flow
+ if ( this.element.getStyle('display') == 'none' )
+ {
+ this.cancel();
+ return;
+ }
+ // Disable background image during the effect
+ this.oldStyle = {
+ backgroundImage: this.element.getStyle('background-image') };
+ this.element.setStyle({backgroundImage: 'none'});
+ if ( !this.options.endcolor )
+ this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+ if ( !this.options.restorecolor )
+ this.options.restorecolor = this.element.getStyle('background-color');
+ // init color calculations
+ this._base = $R(0, 2).map(function( i )
+ {
+ return parseInt(this.options.startcolor.slice(i * 2 + 1, i * 2 + 3), 16)
+ }.bind(this));
+ this._delta = $R(0, 2).map(function( i )
+ {
+ return parseInt(this.options.endcolor.slice(i * 2 + 1, i * 2 + 3), 16) - this._base[i]
+ }.bind(this));
+ },
+ update: function( position )
+ {
+ this.element.setStyle({backgroundColor: $R(0, 2).inject('#', function( m, v, i )
+ {
+ return m + (Math.round(this._base[i] + (this._delta[i] * position)).toColorPart());
+ }.bind(this)) });
+ },
+ finish: function()
+ {
+ this.element.setStyle(Object.extend(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
+ }
+});
+
+Effect.ScrollTo = Class.create();
+Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
+ initialize: function( element )
+ {
+ this.element = $(element);
+ this.start(arguments[1] || {});
+ },
+ setup: function()
+ {
+ Position.prepare();
+ var offsets = Position.cumulativeOffset(this.element);
+ if ( this.options.offset ) offsets[1] += this.options.offset;
+ var max = window.innerHeight ? window.height - window.innerHeight : document.body.scrollHeight -
+ (document.documentElement.clientHeight
+ ? document.documentElement.clientHeight
+ : document.body.clientHeight);
+ this.scrollStart = Position.deltaY;
+ this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
+ },
+ update: function( position )
+ {
+ Position.prepare();
+ window.scrollTo(Position.deltaX, this.scrollStart + (position * this.delta));
+ }
+});
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function( element )
+{
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ var options = Object.extend({
+ from: element.getOpacity() || 1.0,
+ to: 0.0,
+ afterFinishInternal: function( effect )
+ {
+ if ( effect.options.to != 0 ) return;
+ effect.element.hide();
+ effect.element.setStyle({opacity: oldOpacity});
+ }}, arguments[1] || {});
+ return new Effect.Opacity(element, options);
+}
+
+Effect.Appear = function( element )
+{
+ element = $(element);
+ var options = Object.extend({
+ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+ to: 1.0,
+ // force Safari to render floated elements properly
+ afterFinishInternal: function( effect )
+ {
+ effect.element.forceRerendering();
+ },
+ beforeSetup: function( effect )
+ {
+ effect.element.setOpacity(effect.options.from);
+ effect.element.show();
+ }}, arguments[1] || {});
+ return new Effect.Opacity(element, options);
+}
+
+Effect.Puff = function( element )
+{
+ element = $(element);
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
+ position: element.getStyle('position'),
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+ };
+ return new Effect.Parallel([ new Effect.Scale(element, 200, { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 }) ], Object.extend({ duration: 1.0,
+ beforeSetupInternal: function( effect )
+ {
+ Position.absolutize(effect.effects[0].element)
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.BlindUp = function( element )
+{
+ element = $(element);
+ element.makeClipping();
+ return new Effect.Scale(element, 0, Object.extend({ scaleContent: false,
+ scaleX: false,
+ restoreAfterFinish: true,
+ afterFinishInternal: function( effect )
+ {
+ effect.element.hide();
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.BlindDown = function( element )
+{
+ element = $(element);
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function( effect )
+ {
+ effect.element.makeClipping();
+ effect.element.setStyle({height: '0px'});
+ effect.element.show();
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.SwitchOff = function( element )
+{
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ return new Effect.Appear(element, Object.extend({
+ duration: 0.4,
+ from: 0,
+ transition: Effect.Transitions.flicker,
+ afterFinishInternal: function( effect )
+ {
+ new Effect.Scale(effect.element, 1, {
+ duration: 0.3, scaleFromCenter: true,
+ scaleX: false, scaleContent: false, restoreAfterFinish: true,
+ beforeSetup: function( effect )
+ {
+ effect.element.makePositioned();
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.undoPositioned();
+ effect.element.setStyle({opacity: oldOpacity});
+ }
+ })
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.DropOut = function( element )
+{
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left'),
+ opacity: element.getInlineOpacity() };
+ return new Effect.Parallel([ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 }) ], Object.extend({ duration: 0.5,
+ beforeSetup: function( effect )
+ {
+ effect.effects[0].element.makePositioned();
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.Shake = function( element )
+{
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left') };
+ return new Effect.Move(element, { x: 20, y: 0, duration: 0.05, afterFinishInternal: function( effect )
+ {
+ new Effect.Move(effect.element, { x: -40, y: 0, duration: 0.1, afterFinishInternal: function( effect )
+ {
+ new Effect.Move(effect.element, { x: 40, y: 0, duration: 0.1, afterFinishInternal: function( effect )
+ {
+ new Effect.Move(effect.element, { x: -40, y: 0, duration: 0.1, afterFinishInternal: function( effect )
+ {
+ new Effect.Move(effect.element, { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(
+ effect )
+ {
+ new Effect.Move(effect.element, { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(
+ effect )
+ {
+ effect.element.undoPositioned();
+ effect.element.setStyle(oldStyle);
+ }})
+ }})
+ }})
+ }})
+ }})
+ }});
+}
+
+Effect.SlideDown = function( element )
+{
+ element = $(element);
+ element.cleanWhitespace();
+ // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: window.opera ? 0 : 1,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function( effect )
+ {
+ effect.element.makePositioned();
+ effect.element.firstChild.makePositioned();
+ if ( window.opera ) effect.element.setStyle({top: ''});
+ effect.element.makeClipping();
+ effect.element.setStyle({height: '0px'});
+ effect.element.show();
+ },
+ afterUpdateInternal: function( effect )
+ {
+ effect.element.firstChild.setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.element.undoClipping();
+ // IE will crash if child is undoPositioned first
+ if ( /MSIE/.test(navigator.userAgent) && !window.opera )
+ {
+ effect.element.undoPositioned();
+ effect.element.firstChild.undoPositioned();
+ }
+ else
+ {
+ effect.element.firstChild.undoPositioned();
+ effect.element.undoPositioned();
+ }
+ effect.element.firstChild.setStyle({bottom: oldInnerBottom});
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.SlideUp = function( element )
+{
+ element = $(element);
+ element.cleanWhitespace();
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+ return new Effect.Scale(element, window.opera ? 0 : 1, Object.extend({ scaleContent: false,
+ scaleX: false,
+ scaleMode: 'box',
+ scaleFrom: 100,
+ restoreAfterFinish: true,
+ beforeStartInternal: function( effect )
+ {
+ effect.element.makePositioned();
+ effect.element.firstChild.makePositioned();
+ if ( window.opera ) effect.element.setStyle({top: ''});
+ effect.element.makeClipping();
+ effect.element.show();
+ },
+ afterUpdateInternal: function( effect )
+ {
+ effect.element.firstChild.setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.firstChild.undoPositioned();
+ effect.element.undoPositioned();
+ effect.element.setStyle({bottom: oldInnerBottom});
+ }
+ }, arguments[1] || {}));
+}
+
+// Bug in opera makes the TD containing this element expand for a instance after finish
+Effect.Squish = function( element )
+{
+ return new Effect.Scale(element, window.opera ? 1 : 0, { restoreAfterFinish: true,
+ beforeSetup: function( effect )
+ {
+ effect.element.makeClipping(effect.element);
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.element.hide(effect.element);
+ effect.element.undoClipping(effect.element);
+ }
+ });
+}
+
+Effect.Grow = function( element )
+{
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.full
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var initialMoveX, initialMoveY;
+ var moveX, moveY;
+
+ switch ( options.direction )
+ {
+ case 'top-left':
+ initialMoveX = initialMoveY = moveX = moveY = 0;
+ break;
+ case 'top-right':
+ initialMoveX = dims.width;
+ initialMoveY = moveY = 0;
+ moveX = -dims.width;
+ break;
+ case 'bottom-left':
+ initialMoveX = moveX = 0;
+ initialMoveY = dims.height;
+ moveY = -dims.height;
+ break;
+ case 'bottom-right':
+ initialMoveX = dims.width;
+ initialMoveY = dims.height;
+ moveX = -dims.width;
+ moveY = -dims.height;
+ break;
+ case 'center':
+ initialMoveX = dims.width / 2;
+ initialMoveY = dims.height / 2;
+ moveX = -dims.width / 2;
+ moveY = -dims.height / 2;
+ break;
+ }
+
+ return new Effect.Move(element, {
+ x: initialMoveX,
+ y: initialMoveY,
+ duration: 0.01,
+ beforeSetup: function( effect )
+ {
+ effect.element.hide();
+ effect.element.makeClipping();
+ effect.element.makePositioned();
+ },
+ afterFinishInternal: function( effect )
+ {
+ new Effect.Parallel([ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+ new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+ new Effect.Scale(effect.element, 100, {
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ sync: true, scaleFrom: window.opera ? 1
+ : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+ ], Object.extend({
+ beforeSetup: function( effect )
+ {
+ effect.effects[0].element.setStyle({height: '0px'});
+ effect.effects[0].element.show();
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.effects[0].element.undoClipping();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
+ }, options))
+ }
+ });
+}
+
+Effect.Shrink = function( element )
+{
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.none
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var moveX, moveY;
+
+ switch ( options.direction )
+ {
+ case 'top-left':
+ moveX = moveY = 0;
+ break;
+ case 'top-right':
+ moveX = dims.width;
+ moveY = 0;
+ break;
+ case 'bottom-left':
+ moveX = 0;
+ moveY = dims.height;
+ break;
+ case 'bottom-right':
+ moveX = dims.width;
+ moveY = dims.height;
+ break;
+ case 'center':
+ moveX = dims.width / 2;
+ moveY = dims.height / 2;
+ break;
+ }
+
+ return new Effect.Parallel([ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+ new Effect.Scale(element, window.opera ? 1
+ : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+ new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+ ], Object.extend({
+ beforeStartInternal: function( effect )
+ {
+ effect.effects[0].element.makePositioned();
+ effect.effects[0].element.makeClipping();
+ },
+ afterFinishInternal: function( effect )
+ {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.undoClipping();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
+ }, options));
+}
+
+Effect.Pulsate = function( element )
+{
+ element = $(element);
+ var options = arguments[1] || {};
+ var oldOpacity = element.getInlineOpacity();
+ var transition = options.transition || Effect.Transitions.sinoidal;
+ var reverser = function( pos )
+ {
+ return transition(1 - Effect.Transitions.pulse(pos))
+ };
+ reverser.bind(transition);
+ return new Effect.Opacity(element, Object.extend(Object.extend({ duration: 3.0, from: 0,
+ afterFinishInternal: function( effect )
+ {
+ effect.element.setStyle({opacity: oldOpacity});
+ }
+ }, options), {transition: reverser}));
+}
+
+Effect.Fold = function( element )
+{
+ element = $(element);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height };
+ Element.makeClipping(element);
+ return new Effect.Scale(element, 5, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ afterFinishInternal: function( effect )
+ {
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
+ scaleY: false,
+ afterFinishInternal: function( effect )
+ {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.setStyle(oldStyle);
+ } });
+ }}, arguments[1] || {}));
+};
+
+['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
+ 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(function( f )
+{
+ Element.Methods[f] = Element[f];
+});
+
+Element.Methods.visualEffect = function( element, effect, options )
+{
+ s = effect.gsub(/_/, '-').camelize();
+ effect_class = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[effect_class](element, options);
+ return $(element);
+};
+
+Element.addMethods();
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/* Prototype JavaScript framework, version 1.5.0_rc1
+ * (c) 2005 Sam Stephenson <sam@conio.net>
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.5.0_rc1',
+ ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+
+ emptyFunction: function()
+ {
+ },
+ K: function( x )
+ {
+ return x
+ }
+}
+
+var Class = {
+ create: function()
+ {
+ return function()
+ {
+ this.initialize.apply(this, arguments);
+ }
+ }
+}
+
+var Abstract = new Object();
+
+Object.extend = function( destination, source )
+{
+ for ( var property in source )
+ {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+Object.extend(Object, {
+ inspect: function( object )
+ {
+ try
+ {
+ if ( object == undefined ) return 'undefined';
+ if ( object == null ) return 'null';
+ return object.inspect ? object.inspect() : object.toString();
+ }
+ catch ( e )
+ {
+ if ( e instanceof RangeError ) return '...';
+ throw e;
+ }
+ },
+
+ keys: function( object )
+ {
+ var keys = [];
+ for ( var property in object )
+ keys.push(property);
+ return keys;
+ },
+
+ values: function( object )
+ {
+ var values = [];
+ for ( var property in object )
+ values.push(object[property]);
+ return values;
+ },
+
+ clone: function( object )
+ {
+ return Object.extend({}, object);
+ }
+});
+
+Function.prototype.bind = function()
+{
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function()
+ {
+ return __method.apply(object, args.concat($A(arguments)));
+ }
+}
+
+Function.prototype.bindAsEventListener = function( object )
+{
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function( event )
+ {
+ return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
+ }
+}
+
+Object.extend(Number.prototype, {
+ toColorPart: function()
+ {
+ var digits = this.toString(16);
+ if ( this < 16 ) return '0' + digits;
+ return digits;
+ },
+
+ succ: function()
+ {
+ return this + 1;
+ },
+
+ times: function( iterator )
+ {
+ $R(0, this, true).each(iterator);
+ return this;
+ }
+});
+
+var Try = {
+ these: function()
+ {
+ var returnValue;
+
+ for ( var i = 0; i < arguments.length; i++ )
+ {
+ var lambda = arguments[i];
+ try
+ {
+ returnValue = lambda();
+ break;
+ }
+ catch ( e )
+ {
+ }
+ }
+
+ return returnValue;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+ initialize: function( callback, frequency )
+ {
+ this.callback = callback;
+ this.frequency = frequency;
+ this.currentlyExecuting = false;
+
+ this.registerCallback();
+ },
+
+ registerCallback: function()
+ {
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ stop: function()
+ {
+ if ( !this.timer ) return;
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+
+ onTimerEvent: function()
+ {
+ if ( !this.currentlyExecuting )
+ {
+ try
+ {
+ this.currentlyExecuting = true;
+ this.callback(this);
+ }
+ finally
+ {
+ this.currentlyExecuting = false;
+ }
+ }
+ }
+}
+Object.extend(String.prototype, {
+ gsub: function( pattern, replacement )
+ {
+ var result = '', source = this, match;
+ replacement = arguments.callee.prepareReplacement(replacement);
+
+ while ( source.length > 0 )
+ {
+ if ( match = source.match(pattern) )
+ {
+ result += source.slice(0, match.index);
+ result += (replacement(match) || '').toString();
+ source = source.slice(match.index + match[0].length);
+ }
+ else
+ {
+ result += source,source = '';
+ }
+ }
+ return result;
+ },
+
+ sub: function( pattern, replacement, count )
+ {
+ replacement = this.gsub.prepareReplacement(replacement);
+ count = count === undefined ? 1 : count;
+
+ return this.gsub(pattern, function( match )
+ {
+ if ( --count < 0 ) return match[0];
+ return replacement(match);
+ });
+ },
+
+ scan: function( pattern, iterator )
+ {
+ this.gsub(pattern, iterator);
+ return this;
+ },
+
+ truncate: function( length, truncation )
+ {
+ length = length || 30;
+ truncation = truncation === undefined ? '...' : truncation;
+ return this.length > length ? this.slice(0, length - truncation.length) + truncation : this;
+ },
+
+ strip: function()
+ {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ },
+
+ stripTags: function()
+ {
+ return this.replace(/<\/?[^>]+>/gi, '');
+ },
+
+ stripScripts: function()
+ {
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+ },
+
+ extractScripts: function()
+ {
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+ var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+ return (this.match(matchAll) || []).map(function( scriptTag )
+ {
+ return (scriptTag.match(matchOne) || ['', ''])[1];
+ });
+ },
+
+ evalScripts: function()
+ {
+ return this.extractScripts().map(function( script )
+ {
+ return eval(script)
+ });
+ },
+
+ escapeHTML: function()
+ {
+ var div = document.createElement('div');
+ var text = document.createTextNode(this);
+ div.appendChild(text);
+ return div.innerHTML;
+ },
+
+ unescapeHTML: function()
+ {
+ var div = document.createElement('div');
+ div.innerHTML = this.stripTags();
+ return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+ },
+
+ toQueryParams: function()
+ {
+ var pairs = this.match(/^\??(.*)$/)[1].split('&');
+ return pairs.inject({}, function( params, pairString )
+ {
+ var pair = pairString.split('=');
+ var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+ params[decodeURIComponent(pair[0])] = value;
+ return params;
+ });
+ },
+
+ toArray: function()
+ {
+ return this.split('');
+ },
+
+ camelize: function()
+ {
+ var oStringList = this.split('-');
+ if ( oStringList.length == 1 ) return oStringList[0];
+
+ var camelizedString = this.indexOf('-') == 0 ? oStringList[0].charAt(0).toUpperCase() +
+ oStringList[0].substring(1) : oStringList[0];
+
+ for ( var i = 1, len = oStringList.length; i < len; i++ )
+ {
+ var s = oStringList[i];
+ camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
+ }
+
+ return camelizedString;
+ },
+
+ inspect: function( useDoubleQuotes )
+ {
+ var escapedString = this.replace(/\\/g, '\\\\');
+ if ( useDoubleQuotes )
+ return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ else
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+ }
+});
+
+String.prototype.gsub.prepareReplacement = function( replacement )
+{
+ if ( typeof replacement == 'function' ) return replacement;
+ var template = new Template(replacement);
+ return function( match )
+ {
+ return template.evaluate(match)
+ };
+}
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+ initialize: function( template, pattern )
+ {
+ this.template = template.toString();
+ this.pattern = pattern || Template.Pattern;
+ },
+
+ evaluate: function( object )
+ {
+ return this.template.gsub(this.pattern, function( match )
+ {
+ var before = match[1];
+ if ( before == '\\' ) return match[2];
+ return before + (object[match[3]] || '').toString();
+ });
+ }
+}
+
+var $break = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+ each: function( iterator )
+ {
+ var index = 0;
+ try
+ {
+ this._each(function( value )
+ {
+ try
+ {
+ iterator(value, index++);
+ }
+ catch ( e )
+ {
+ if ( e != $continue ) throw e;
+ }
+ });
+ }
+ catch ( e )
+ {
+ if ( e != $break ) throw e;
+ }
+ },
+
+ all: function( iterator )
+ {
+ var result = true;
+ this.each(function( value, index )
+ {
+ result = result && !!(iterator || Prototype.K)(value, index);
+ if ( !result ) throw $break;
+ });
+ return result;
+ },
+
+ any: function( iterator )
+ {
+ var result = false;
+ this.each(function( value, index )
+ {
+ if ( result = !!(iterator || Prototype.K)(value, index) )
+ throw $break;
+ });
+ return result;
+ },
+
+ collect: function( iterator )
+ {
+ var results = [];
+ this.each(function( value, index )
+ {
+ results.push(iterator(value, index));
+ });
+ return results;
+ },
+
+ detect: function ( iterator )
+ {
+ var result;
+ this.each(function( value, index )
+ {
+ if ( iterator(value, index) )
+ {
+ result = value;
+ throw $break;
+ }
+ });
+ return result;
+ },
+
+ findAll: function( iterator )
+ {
+ var results = [];
+ this.each(function( value, index )
+ {
+ if ( iterator(value, index) )
+ results.push(value);
+ });
+ return results;
+ },
+
+ grep: function( pattern, iterator )
+ {
+ var results = [];
+ this.each(function( value, index )
+ {
+ var stringValue = value.toString();
+ if ( stringValue.match(pattern) )
+ results.push((iterator || Prototype.K)(value, index));
+ })
+ return results;
+ },
+
+ include: function( object )
+ {
+ var found = false;
+ this.each(function( value )
+ {
+ if ( value == object )
+ {
+ found = true;
+ throw $break;
+ }
+ });
+ return found;
+ },
+
+ inject: function( memo, iterator )
+ {
+ this.each(function( value, index )
+ {
+ memo = iterator(memo, value, index);
+ });
+ return memo;
+ },
+
+ invoke: function( method )
+ {
+ var args = $A(arguments).slice(1);
+ return this.collect(function( value )
+ {
+ return value[method].apply(value, args);
+ });
+ },
+
+ max: function( iterator )
+ {
+ var result;
+ this.each(function( value, index )
+ {
+ value = (iterator || Prototype.K)(value, index);
+ if ( result == undefined || value >= result )
+ result = value;
+ });
+ return result;
+ },
+
+ min: function( iterator )
+ {
+ var result;
+ this.each(function( value, index )
+ {
+ value = (iterator || Prototype.K)(value, index);
+ if ( result == undefined || value < result )
+ result = value;
+ });
+ return result;
+ },
+
+ partition: function( iterator )
+ {
+ var trues = [], falses = [];
+ this.each(function( value, index )
+ {
+ ((iterator || Prototype.K)(value, index) ? trues : falses).push(value);
+ });
+ return [trues, falses];
+ },
+
+ pluck: function( property )
+ {
+ var results = [];
+ this.each(function( value, index )
+ {
+ results.push(value[property]);
+ });
+ return results;
+ },
+
+ reject: function( iterator )
+ {
+ var results = [];
+ this.each(function( value, index )
+ {
+ if ( !iterator(value, index) )
+ results.push(value);
+ });
+ return results;
+ },
+
+ sortBy: function( iterator )
+ {
+ return this.collect(function( value, index )
+ {
+ return {value: value, criteria: iterator(value, index)};
+ }).sort(function( left, right )
+ {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }).pluck('value');
+ },
+
+ toArray: function()
+ {
+ return this.collect(Prototype.K);
+ },
+
+ zip: function()
+ {
+ var iterator = Prototype.K, args = $A(arguments);
+ if ( typeof args.last() == 'function' )
+ iterator = args.pop();
+
+ var collections = [this].concat(args).map($A);
+ return this.map(function( value, index )
+ {
+ return iterator(collections.pluck(index));
+ });
+ },
+
+ inspect: function()
+ {
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
+ }
+}
+
+Object.extend(Enumerable, {
+ map: Enumerable.collect,
+ find: Enumerable.detect,
+ select: Enumerable.findAll,
+ member: Enumerable.include,
+ entries: Enumerable.toArray
+});
+var $A = Array.from = function( iterable )
+{
+ if ( !iterable ) return [];
+ if ( iterable.toArray )
+ {
+ return iterable.toArray();
+ }
+ else
+ {
+ var results = [];
+ for ( var i = 0; i < iterable.length; i++ )
+ results.push(iterable[i]);
+ return results;
+ }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+if ( !Array.prototype._reverse )
+ Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+ _each: function( iterator )
+ {
+ for ( var i = 0; i < this.length; i++ )
+ iterator(this[i]);
+ },
+
+ clear: function()
+ {
+ this.length = 0;
+ return this;
+ },
+
+ first: function()
+ {
+ return this[0];
+ },
+
+ last: function()
+ {
+ return this[this.length - 1];
+ },
+
+ compact: function()
+ {
+ return this.select(function( value )
+ {
+ return value != undefined || value != null;
+ });
+ },
+
+ flatten: function()
+ {
+ return this.inject([], function( array, value )
+ {
+ return array.concat(value && value.constructor == Array ? value.flatten() : [value]);
+ });
+ },
+
+ without: function()
+ {
+ var values = $A(arguments);
+ return this.select(function( value )
+ {
+ return !values.include(value);
+ });
+ },
+
+ indexOf: function( object )
+ {
+ for ( var i = 0; i < this.length; i++ )
+ if ( this[i] == object ) return i;
+ return -1;
+ },
+
+ reverse: function( inline )
+ {
+ return (inline !== false ? this : this.toArray())._reverse();
+ },
+
+ reduce: function()
+ {
+ return this.length > 1 ? this : this[0];
+ },
+
+ uniq: function()
+ {
+ return this.inject([], function( array, value )
+ {
+ return array.include(value) ? array : array.concat([value]);
+ });
+ },
+
+ inspect: function()
+ {
+ return '[' + this.map(Object.inspect).join(', ') + ']';
+ }
+});
+var Hash = {
+ _each: function( iterator )
+ {
+ for ( var key in this )
+ {
+ var value = this[key];
+ if ( typeof value == 'function' ) continue;
+
+ var pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
+ }
+ },
+
+ keys: function()
+ {
+ return this.pluck('key');
+ },
+
+ values: function()
+ {
+ return this.pluck('value');
+ },
+
+ merge: function( hash )
+ {
+ return $H(hash).inject($H(this), function( mergedHash, pair )
+ {
+ mergedHash[pair.key] = pair.value;
+ return mergedHash;
+ });
+ },
+
+ toQueryString: function()
+ {
+ return this.map(function( pair )
+ {
+ return pair.map(encodeURIComponent).join('=');
+ }).join('&');
+ },
+
+ inspect: function()
+ {
+ return '#<Hash:{' + this.map(function( pair )
+ {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ }
+}
+
+function $H( object )
+{
+ var hash = Object.extend({}, object || {});
+ Object.extend(hash, Enumerable);
+ Object.extend(hash, Hash);
+ return hash;
+}
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+ initialize: function( start, end, exclusive )
+ {
+ this.start = start;
+ this.end = end;
+ this.exclusive = exclusive;
+ },
+
+ _each: function( iterator )
+ {
+ var value = this.start;
+ while ( this.include(value) )
+ {
+ iterator(value);
+ value = value.succ();
+ }
+ },
+
+ include: function( value )
+ {
+ if ( value < this.start )
+ return false;
+ if ( this.exclusive )
+ return value < this.end;
+ return value <= this.end;
+ }
+});
+
+var $R = function( start, end, exclusive )
+{
+ return new ObjectRange(start, end, exclusive);
+}
+
+var Ajax = {
+ getTransport: function()
+ {
+ return Try.these(function()
+ {
+ return new XMLHttpRequest()
+ }, function()
+ {
+ return new ActiveXObject('Msxml2.XMLHTTP')
+ }, function()
+ {
+ return new ActiveXObject('Microsoft.XMLHTTP')
+ }) || false;
+ },
+
+ activeRequestCount: 0
+}
+
+Ajax.Responders = {
+ responders: [],
+
+ _each: function( iterator )
+ {
+ this.responders._each(iterator);
+ },
+
+ register: function( responderToAdd )
+ {
+ if ( !this.include(responderToAdd) )
+ this.responders.push(responderToAdd);
+ },
+
+ unregister: function( responderToRemove )
+ {
+ this.responders = this.responders.without(responderToRemove);
+ },
+
+ dispatch: function( callback, request, transport, json )
+ {
+ this.each(function( responder )
+ {
+ if ( responder[callback] && typeof responder[callback] == 'function' )
+ {
+ try
+ {
+ responder[callback].apply(responder, [request, transport, json]);
+ }
+ catch ( e )
+ {
+ }
+ }
+ });
+ }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+ onCreate: function()
+ {
+ Ajax.activeRequestCount++;
+ },
+
+ onComplete: function()
+ {
+ Ajax.activeRequestCount--;
+ }
+});
+
+Ajax.Base = function()
+{
+};
+Ajax.Base.prototype = {
+ setOptions: function( options )
+ {
+ this.options = {
+ method: 'post',
+ asynchronous: true,
+ contentType: 'application/x-www-form-urlencoded',
+ parameters: ''
+ }
+ Object.extend(this.options, options || {});
+ },
+
+ responseIsSuccess: function()
+ {
+ return this.transport.status == undefined || this.transport.status == 0 ||
+ (this.transport.status >= 200 && this.transport.status < 300);
+ },
+
+ responseIsFailure: function()
+ {
+ return !this.responseIsSuccess();
+ }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+ initialize: function( url, options )
+ {
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+ this.request(url);
+ },
+
+ request: function( url )
+ {
+ var parameters = this.options.parameters || '';
+ if ( parameters.length > 0 ) parameters += '&_=';
+
+ /* Simulate other verbs over post */
+ if ( this.options.method != 'get' && this.options.method != 'post' )
+ {
+ parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method;
+ this.options.method = 'post';
+ }
+
+ try
+ {
+ this.url = url;
+ if ( this.options.method == 'get' && parameters.length > 0 )
+ this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
+
+ Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+ this.transport.open(this.options.method, this.url, this.options.asynchronous);
+
+ if ( this.options.asynchronous )
+ setTimeout(function()
+ {
+ this.respondToReadyState(1)
+ }.bind(this), 10);
+
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ this.setRequestHeaders();
+
+ var body = this.options.postBody ? this.options.postBody : parameters;
+ this.transport.send(this.options.method == 'post' ? body : null);
+
+ /* Force Firefox to handle ready state 4 for synchronous requests */
+ if ( !this.options.asynchronous && this.transport.overrideMimeType )
+ this.onStateChange();
+
+ }
+ catch ( e )
+ {
+ this.dispatchException(e);
+ }
+ },
+
+ setRequestHeaders: function()
+ {
+ var requestHeaders = ['X-Requested-With', 'XMLHttpRequest',
+ 'X-Prototype-Version', Prototype.Version,
+ 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
+
+ if ( this.options.method == 'post' )
+ {
+ requestHeaders.push('Content-type', this.options.contentType);
+
+ /* Force "Connection: close" for Mozilla browsers to work around
+ * a bug where XMLHttpReqeuest sends an incorrect Content-length
+ * header. See Mozilla Bugzilla #246651.
+ */
+ if ( this.transport.overrideMimeType )
+ requestHeaders.push('Connection', 'close');
+ }
+
+ if ( this.options.requestHeaders )
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
+
+ for ( var i = 0; i < requestHeaders.length; i += 2 )
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i + 1]);
+ },
+
+ onStateChange: function()
+ {
+ var readyState = this.transport.readyState;
+ if ( readyState != 1 )
+ this.respondToReadyState(this.transport.readyState);
+ },
+
+ header: function( name )
+ {
+ try
+ {
+ return this.transport.getResponseHeader(name);
+ }
+ catch ( e )
+ {
+ }
+ },
+
+ evalJSON: function()
+ {
+ try
+ {
+ return eval('(' + this.header('X-JSON') + ')');
+ }
+ catch ( e )
+ {
+ }
+ },
+
+ evalResponse: function()
+ {
+ try
+ {
+ return eval(this.transport.responseText);
+ }
+ catch ( e )
+ {
+ this.dispatchException(e);
+ }
+ },
+
+ respondToReadyState: function( readyState )
+ {
+ var event = Ajax.Request.Events[readyState];
+ var transport = this.transport, json = this.evalJSON();
+
+ if ( event == 'Complete' )
+ {
+ try
+ {
+ (this.options['on' + this.transport.status] ||
+ this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] ||
+ Prototype.emptyFunction)(transport, json);
+ }
+ catch ( e )
+ {
+ this.dispatchException(e);
+ }
+
+ if ( (this.header('Content-type') || '').match(/^text\/javascript/i) )
+ this.evalResponse();
+ }
+
+ try
+ {
+ (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + event, this, transport, json);
+ }
+ catch ( e )
+ {
+ this.dispatchException(e);
+ }
+
+ /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
+ if ( event == 'Complete' )
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ },
+
+ dispatchException: function( exception )
+ {
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
+ Ajax.Responders.dispatch('onException', this, exception);
+ }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+ initialize: function( container, url, options )
+ {
+ this.containers = {
+ success: container.success ? $(container.success) : $(container),
+ failure: container.failure ? $(container.failure) : (container.success ? null : $(container))
+ }
+
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
+ this.options.onComplete = (function( transport, object )
+ {
+ this.updateContent();
+ onComplete(transport, object);
+ }).bind(this);
+
+ this.request(url);
+ },
+
+ updateContent: function()
+ {
+ var receiver = this.responseIsSuccess() ? this.containers.success : this.containers.failure;
+ var response = this.transport.responseText;
+
+ if ( !this.options.evalScripts )
+ response = response.stripScripts();
+
+ if ( receiver )
+ {
+ if ( this.options.insertion )
+ {
+ new this.options.insertion(receiver, response);
+ }
+ else
+ {
+ Element.update(receiver, response);
+ }
+ }
+
+ if ( this.responseIsSuccess() )
+ {
+ if ( this.onComplete )
+ setTimeout(this.onComplete.bind(this), 10);
+ }
+ }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+ initialize: function( container, url, options )
+ {
+ this.setOptions(options);
+ this.onComplete = this.options.onComplete;
+
+ this.frequency = (this.options.frequency || 2);
+ this.decay = (this.options.decay || 1);
+
+ this.updater = {};
+ this.container = container;
+ this.url = url;
+
+ this.start();
+ },
+
+ start: function()
+ {
+ this.options.onComplete = this.updateComplete.bind(this);
+ this.onTimerEvent();
+ },
+
+ stop: function()
+ {
+ this.updater.options.onComplete = undefined;
+ clearTimeout(this.timer);
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+ },
+
+ updateComplete: function( request )
+ {
+ if ( this.options.decay )
+ {
+ this.decay = (request.responseText == this.lastText ? this.decay * this.options.decay : 1);
+
+ this.lastText = request.responseText;
+ }
+ this.timer = setTimeout(this.onTimerEvent.bind(this), this.decay * this.frequency * 1000);
+ },
+
+ onTimerEvent: function()
+ {
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
+ }
+});
+function $()
+{
+ var results = [], element;
+ for ( var i = 0; i < arguments.length; i++ )
+ {
+ element = arguments[i];
+ if ( typeof element == 'string' )
+ element = document.getElementById(element);
+ results.push(Element.extend(element));
+ }
+ return results.reduce();
+}
+
+document.getElementsByClassName = function( className, parentElement )
+{
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
+ return $A(children).inject([], function( elements, child )
+ {
+ if ( child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")) )
+ elements.push(Element.extend(child));
+ return elements;
+ });
+}
+
+/*--------------------------------------------------------------------------*/
+
+if ( !window.Element )
+ var Element = new Object();
+
+Element.extend = function( element )
+{
+ if ( !element ) return;
+ if ( _nativeExtensions || element.nodeType == 3 ) return element;
+
+ if ( !element._extended && element.tagName && element != window )
+ {
+ var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+ if ( element.tagName == 'FORM' )
+ Object.extend(methods, Form.Methods);
+ if ( ['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName) )
+ Object.extend(methods, Form.Element.Methods);
+
+ for ( var property in methods )
+ {
+ var value = methods[property];
+ if ( typeof value == 'function' )
+ element[property] = cache.findOrStore(value);
+ }
+ }
+
+ element._extended = true;
+ return element;
+}
+
+Element.extend.cache = {
+ findOrStore: function( value )
+ {
+ return this[value] = this[value] || function()
+ {
+ return value.apply(null, [this].concat($A(arguments)));
+ }
+ }
+}
+
+Element.Methods = {
+ visible: function( element )
+ {
+ return $(element).style.display != 'none';
+ },
+
+ toggle: function( element )
+ {
+ element = $(element);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ return element;
+ },
+
+ hide: function( element )
+ {
+ $(element).style.display = 'none';
+ return element;
+ },
+
+ show: function( element )
+ {
+ $(element).style.display = '';
+ return element;
+ },
+
+ remove: function( element )
+ {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ return element;
+ },
+
+ update: function( element, html )
+ {
+ $(element).innerHTML = html.stripScripts();
+ setTimeout(function()
+ {
+ html.evalScripts()
+ }, 10);
+ return element;
+ },
+
+ replace: function( element, html )
+ {
+ element = $(element);
+ if ( element.outerHTML )
+ {
+ element.outerHTML = html.stripScripts();
+ }
+ else
+ {
+ var range = element.ownerDocument.createRange();
+ range.selectNodeContents(element);
+ element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);
+ }
+ setTimeout(function()
+ {
+ html.evalScripts()
+ }, 10);
+ return element;
+ },
+
+ inspect: function( element )
+ {
+ element = $(element);
+ var result = '<' + element.tagName.toLowerCase();
+ $H({'id': 'id', 'className': 'class'}).each(function( pair )
+ {
+ var property = pair.first(), attribute = pair.last();
+ var value = (element[property] || '').toString();
+ if ( value ) result += ' ' + attribute + '=' + value.inspect(true);
+ });
+ return result + '>';
+ },
+
+ recursivelyCollect: function( element, property )
+ {
+ element = $(element);
+ var elements = [];
+ while ( element = element[property] )
+ if ( element.nodeType == 1 )
+ elements.push(Element.extend(element));
+ return elements;
+ },
+
+ ancestors: function( element )
+ {
+ return $(element).recursivelyCollect('parentNode');
+ },
+
+ descendants: function( element )
+ {
+ element = $(element);
+ return $A(element.getElementsByTagName('*'));
+ },
+
+ previousSiblings: function( element )
+ {
+ return $(element).recursivelyCollect('previousSibling');
+ },
+
+ nextSiblings: function( element )
+ {
+ return $(element).recursivelyCollect('nextSibling');
+ },
+
+ siblings: function( element )
+ {
+ element = $(element);
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
+ },
+
+ match: function( element, selector )
+ {
+ element = $(element);
+ if ( typeof selector == 'string' )
+ selector = new Selector(selector);
+ return selector.match(element);
+ },
+
+ up: function( element, expression, index )
+ {
+ return Selector.findElement($(element).ancestors(), expression, index);
+ },
+
+ down: function( element, expression, index )
+ {
+ return Selector.findElement($(element).descendants(), expression, index);
+ },
+
+ previous: function( element, expression, index )
+ {
+ return Selector.findElement($(element).previousSiblings(), expression, index);
+ },
+
+ next: function( element, expression, index )
+ {
+ return Selector.findElement($(element).nextSiblings(), expression, index);
+ },
+
+ getElementsBySelector: function()
+ {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element, args);
+ },
+
+ getElementsByClassName: function( element, className )
+ {
+ element = $(element);
+ return document.getElementsByClassName(className, element);
+ },
+
+ getHeight: function( element )
+ {
+ element = $(element);
+ return element.offsetHeight;
+ },
+
+ classNames: function( element )
+ {
+ return new Element.ClassNames(element);
+ },
+
+ hasClassName: function( element, className )
+ {
+ if ( !(element = $(element)) ) return;
+ return Element.classNames(element).include(className);
+ },
+
+ addClassName: function( element, className )
+ {
+ if ( !(element = $(element)) ) return;
+ Element.classNames(element).add(className);
+ return element;
+ },
+
+ removeClassName: function( element, className )
+ {
+ if ( !(element = $(element)) ) return;
+ Element.classNames(element).remove(className);
+ return element;
+ },
+
+ observe: function()
+ {
+ Event.observe.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+ stopObserving: function()
+ {
+ Event.stopObserving.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+// removes whitespace-only text node children
+ cleanWhitespace: function( element )
+ {
+ element = $(element);
+ var node = element.firstChild;
+ while ( node )
+ {
+ var nextNode = node.nextSibling;
+ if ( node.nodeType == 3 && !/\S/.test(node.nodeValue) )
+ element.removeChild(node);
+ node = nextNode;
+ }
+ return element;
+ },
+
+ empty: function( element )
+ {
+ return $(element).innerHTML.match(/^\s*$/);
+ },
+
+ childOf: function( element, ancestor )
+ {
+ element = $(element),ancestor = $(ancestor);
+ while ( element = element.parentNode )
+ if ( element == ancestor ) return true;
+ return false;
+ },
+
+ scrollTo: function( element )
+ {
+ element = $(element);
+ var x = element.x ? element.x : element.offsetLeft,
+ y = element.y ? element.y : element.offsetTop;
+ window.scrollTo(x, y);
+ return element;
+ },
+
+ getStyle: function( element, style )
+ {
+ element = $(element);
+ var value = element.style[style.camelize()];
+ if ( !value )
+ {
+ if ( document.defaultView && document.defaultView.getComputedStyle )
+ {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css.getPropertyValue(style) : null;
+ }
+ else if ( element.currentStyle )
+ {
+ value = element.currentStyle[style.camelize()];
+ }
+ }
+
+ if ( window.opera && ['left', 'top', 'right', 'bottom'].include(style) )
+ if ( Element.getStyle(element, 'position') == 'static' ) value = 'auto';
+
+ return value == 'auto' ? null : value;
+ },
+
+ setStyle: function( element, style )
+ {
+ element = $(element);
+ for ( var name in style )
+ element.style[name.camelize()] = style[name];
+ return element;
+ },
+
+ getDimensions: function( element )
+ {
+ element = $(element);
+ if ( Element.getStyle(element, 'display') != 'none' )
+ return {width: element.offsetWidth, height: element.offsetHeight};
+
+ // All *Width and *Height properties give 0 on elements with display none,
+ // so enable the element temporarily
+ var els = element.style;
+ var originalVisibility = els.visibility;
+ var originalPosition = els.position;
+ els.visibility = 'hidden';
+ els.position = 'absolute';
+ els.display = '';
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ els.display = 'none';
+ els.position = originalPosition;
+ els.visibility = originalVisibility;
+ return {width: originalWidth, height: originalHeight};
+ },
+
+ makePositioned: function( element )
+ {
+ element = $(element);
+ var pos = Element.getStyle(element, 'position');
+ if ( pos == 'static' || !pos )
+ {
+ element._madePositioned = true;
+ element.style.position = 'relative';
+ // Opera returns the offset relative to the positioning context, when an
+ // element is position relative but top and left have not been defined
+ if ( window.opera )
+ {
+ element.style.top = 0;
+ element.style.left = 0;
+ }
+ }
+ return element;
+ },
+
+ undoPositioned: function( element )
+ {
+ element = $(element);
+ if ( element._madePositioned )
+ {
+ element._madePositioned = undefined;
+ element.style.position =
+ element.style.top = element.style.left = element.style.bottom = element.style.right = '';
+ }
+ return element;
+ },
+
+ makeClipping: function( element )
+ {
+ element = $(element);
+ if ( element._overflow ) return;
+ element._overflow = element.style.overflow || 'auto';
+ if ( (Element.getStyle(element, 'overflow') || 'visible') != 'hidden' )
+ element.style.overflow = 'hidden';
+ return element;
+ },
+
+ undoClipping: function( element )
+ {
+ element = $(element);
+ if ( !element._overflow ) return;
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+ element._overflow = null;
+ return element;
+ }
+}
+
+// IE is missing .innerHTML support for TABLE-related elements
+if ( document.all )
+{
+ Element.Methods.update = function( element, html )
+ {
+ element = $(element);
+ var tagName = element.tagName.toUpperCase();
+ if ( ['THEAD','TBODY','TR','TD'].indexOf(tagName) > -1 )
+ {
+ var div = document.createElement('div');
+ switch ( tagName )
+ {
+ case 'THEAD':
+ case 'TBODY':
+ div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
+ depth = 2;
+ break;
+ case 'TR':
+ div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
+ depth = 3;
+ break;
+ case 'TD':
+ div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
+ depth = 4;
+ }
+ $A(element.childNodes).each(function( node )
+ {
+ element.removeChild(node)
+ });
+ depth.times(function()
+ {
+ div = div.firstChild
+ });
+
+ $A(div.childNodes).each(function( node )
+ {
+ element.appendChild(node)
+ });
+ }
+ else
+ {
+ element.innerHTML = html.stripScripts();
+ }
+ setTimeout(function()
+ {
+ html.evalScripts()
+ }, 10);
+ return element;
+ }
+}
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if ( !window.HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent) )
+{
+ /* Emulate HTMLElement, HTMLFormElement, HTMLInputElement, HTMLTextAreaElement,
+and HTMLSelectElement in Safari */
+ ['', 'Form', 'Input', 'TextArea', 'Select'].each(function( tag )
+ {
+ var klass = window['HTML' + tag + 'Element'] = {};
+ klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+ });
+}
+
+Element.addMethods = function( methods )
+{
+ Object.extend(Element.Methods, methods || {});
+
+ function copy( methods, destination )
+ {
+ var cache = Element.extend.cache;
+ for ( var property in methods )
+ {
+ var value = methods[property];
+ destination[property] = cache.findOrStore(value);
+ }
+ }
+
+ if ( typeof HTMLElement != 'undefined' )
+ {
+ copy(Element.Methods, HTMLElement.prototype);
+ copy(Form.Methods, HTMLFormElement.prototype);
+ [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function( klass )
+ {
+ copy(Form.Element.Methods, klass.prototype);
+ });
+ _nativeExtensions = true;
+ }
+}
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function( adjacency )
+{
+ this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+ initialize: function( element, content )
+ {
+ this.element = $(element);
+ this.content = content.stripScripts();
+
+ if ( this.adjacency && this.element.insertAdjacentHTML )
+ {
+ try
+ {
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
+ }
+ catch ( e )
+ {
+ var tagName = this.element.tagName.toLowerCase();
+ if ( tagName == 'tbody' || tagName == 'tr' )
+ {
+ this.insertContent(this.contentFromAnonymousTable());
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ else
+ {
+ this.range = this.element.ownerDocument.createRange();
+ if ( this.initializeRange ) this.initializeRange();
+ this.insertContent([this.range.createContextualFragment(this.content)]);
+ }
+
+ setTimeout(function()
+ {
+ content.evalScripts()
+ }, 10);
+ },
+
+ contentFromAnonymousTable: function()
+ {
+ var div = document.createElement('div');
+ div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+ return $A(div.childNodes[0].childNodes[0].childNodes);
+ }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+ initializeRange: function()
+ {
+ this.range.setStartBefore(this.element);
+ },
+
+ insertContent: function( fragments )
+ {
+ fragments.each((function( fragment )
+ {
+ this.element.parentNode.insertBefore(fragment, this.element);
+ }).bind(this));
+ }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+ initializeRange: function()
+ {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(true);
+ },
+
+ insertContent: function( fragments )
+ {
+ fragments.reverse(false).each((function( fragment )
+ {
+ this.element.insertBefore(fragment, this.element.firstChild);
+ }).bind(this));
+ }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+ initializeRange: function()
+ {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(this.element);
+ },
+
+ insertContent: function( fragments )
+ {
+ fragments.each((function( fragment )
+ {
+ this.element.appendChild(fragment);
+ }).bind(this));
+ }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+ initializeRange: function()
+ {
+ this.range.setStartAfter(this.element);
+ },
+
+ insertContent: function( fragments )
+ {
+ fragments.each((function( fragment )
+ {
+ this.element.parentNode.insertBefore(fragment, this.element.nextSibling);
+ }).bind(this));
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+ initialize: function( element )
+ {
+ this.element = $(element);
+ },
+
+ _each: function( iterator )
+ {
+ this.element.className.split(/\s+/).select(function( name )
+ {
+ return name.length > 0;
+ })._each(iterator);
+ },
+
+ set: function( className )
+ {
+ this.element.className = className;
+ },
+
+ add: function( classNameToAdd )
+ {
+ if ( this.include(classNameToAdd) ) return;
+ this.set(this.toArray().concat(classNameToAdd).join(' '));
+ },
+
+ remove: function( classNameToRemove )
+ {
+ if ( !this.include(classNameToRemove) ) return;
+ this.set(this.select(function( className )
+ {
+ return className != classNameToRemove;
+ }).join(' '));
+ },
+
+ toString: function()
+ {
+ return this.toArray().join(' ');
+ }
+}
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+ initialize: function( expression )
+ {
+ this.params = {classNames: []};
+ this.expression = expression.toString().strip();
+ this.parseExpression();
+ this.compileMatcher();
+ },
+
+ parseExpression: function()
+ {
+ function abort( message )
+ {
+ throw 'Parse error in selector: ' + message;
+ }
+
+ if ( this.expression == '' ) abort('empty expression');
+
+ var params = this.params, expr = this.expression, match, modifier, clause, rest;
+ while ( match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i) )
+ {
+ params.attributes = params.attributes || [];
+ params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+ expr = match[1];
+ }
+
+ if ( expr == '*' ) return this.params.wildcard = true;
+
+ while ( match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i) )
+ {
+ modifier = match[1],clause = match[2],rest = match[3];
+ switch ( modifier )
+ {
+ case '#': params.id = clause; break;
+ case '.': params.classNames.push(clause); break;
+ case '':
+ case undefined: params.tagName = clause.toUpperCase(); break;
+ default: abort(expr.inspect());
+ }
+ expr = rest;
+ }
+
+ if ( expr.length > 0 ) abort(expr.inspect());
+ },
+
+ buildMatchExpression: function()
+ {
+ var params = this.params, conditions = [], clause;
+
+ if ( params.wildcard )
+ conditions.push('true');
+ if ( clause = params.id )
+ conditions.push('element.id == ' + clause.inspect());
+ if ( clause = params.tagName )
+ conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+ if ( (clause = params.classNames).length > 0 )
+ for ( var i = 0; i < clause.length; i++ )
+ conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
+ if ( clause = params.attributes )
+ {
+ clause.each(function( attribute )
+ {
+ var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
+ var splitValueBy = function( delimiter )
+ {
+ return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+ }
+
+ switch ( attribute.operator )
+ {
+ case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
+ case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() +
+ ')'); break;
+ case '|=': conditions.push(splitValueBy('-') + '.first().toUpperCase() == ' +
+ attribute.value.toUpperCase().inspect()); break;
+ case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
+ case '':
+ case undefined: conditions.push(value + ' != null'); break;
+ default: throw 'Unknown operator ' + attribute.operator + ' in selector';
+ }
+ });
+ }
+
+ return conditions.join(' && ');
+ },
+
+ compileMatcher: function()
+ {
+ this.match = new Function('element', 'if (!element.tagName) return false; \
+ return ' + this.buildMatchExpression());
+ },
+
+ findElements: function( scope )
+ {
+ var element;
+
+ if ( element = $(this.params.id) )
+ if ( this.match(element) )
+ if ( !scope || Element.childOf(element, scope) )
+ return [element];
+
+ scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+ var results = [];
+ for ( var i = 0; i < scope.length; i++ )
+ if ( this.match(element = scope[i]) )
+ results.push(Element.extend(element));
+
+ return results;
+ },
+
+ toString: function()
+ {
+ return this.expression;
+ }
+}
+
+Object.extend(Selector, {
+ matchElements: function( elements, expression )
+ {
+ var selector = new Selector(expression);
+ return elements.select(selector.match.bind(selector));
+ },
+
+ findElement: function( elements, expression, index )
+ {
+ if ( typeof expression == 'number' ) index = expression,expression = false;
+ return Selector.matchElements(elements, expression || '*')[index || 0];
+ },
+
+ findChildElements: function( element, expressions )
+ {
+ return expressions.map(function( expression )
+ {
+ return expression.strip().split(/\s+/).inject([null], function( results, expr )
+ {
+ var selector = new Selector(expr);
+ return results.inject([], function( elements, result )
+ {
+ return elements.concat(selector.findElements(result || element));
+ });
+ });
+ }).flatten();
+ }
+});
+
+function $$()
+{
+ return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+ reset: function( form )
+ {
+ $(form).reset();
+ return form;
+ }
+};
+
+Form.Methods = {
+ serialize: function( form )
+ {
+ var elements = Form.getElements($(form));
+ var queryComponents = new Array();
+
+ for ( var i = 0; i < elements.length; i++ )
+ {
+ var queryComponent = Form.Element.serialize(elements[i]);
+ if ( queryComponent )
+ queryComponents.push(queryComponent);
+ }
+
+ return queryComponents.join('&');
+ },
+
+ getElements: function( form )
+ {
+ form = $(form);
+ var elements = new Array();
+
+ for ( var tagName in Form.Element.Serializers )
+ {
+ var tagElements = form.getElementsByTagName(tagName);
+ for ( var j = 0; j < tagElements.length; j++ )
+ elements.push(tagElements[j]);
+ }
+ return elements;
+ },
+
+ getInputs: function( form, typeName, name )
+ {
+ form = $(form);
+ var inputs = form.getElementsByTagName('input');
+
+ if ( !typeName && !name )
+ return inputs;
+
+ var matchingInputs = new Array();
+ for ( var i = 0; i < inputs.length; i++ )
+ {
+ var input = inputs[i];
+ if ( (typeName && input.type != typeName) || (name && input.name != name) )
+ continue;
+ matchingInputs.push(input);
+ }
+
+ return matchingInputs;
+ },
+
+ disable: function( form )
+ {
+ form = $(form);
+ var elements = Form.getElements(form);
+ for ( var i = 0; i < elements.length; i++ )
+ {
+ var element = elements[i];
+ element.blur();
+ element.disabled = 'true';
+ }
+ return form;
+ },
+
+ enable: function( form )
+ {
+ form = $(form);
+ var elements = Form.getElements(form);
+ for ( var i = 0; i < elements.length; i++ )
+ {
+ var element = elements[i];
+ element.disabled = '';
+ }
+ return form;
+ },
+
+ findFirstElement: function( form )
+ {
+ return Form.getElements(form).find(function( element )
+ {
+ return element.type != 'hidden' && !element.disabled &&
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
+ focusFirstElement: function( form )
+ {
+ form = $(form);
+ Field.activate(Form.findFirstElement(form));
+ return form;
+ }
+}
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+ focus: function( element )
+ {
+ $(element).focus();
+ return element;
+ },
+
+ select: function( element )
+ {
+ $(element).select();
+ return element;
+ }
+}
+
+Form.Element.Methods = {
+ serialize: function( element )
+ {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if ( parameter )
+ {
+ var key = encodeURIComponent(parameter[0]);
+ if ( key.length == 0 ) return;
+
+ if ( parameter[1].constructor != Array )
+ parameter[1] = [parameter[1]];
+
+ return parameter[1].map(function( value )
+ {
+ return key + '=' + encodeURIComponent(value);
+ }).join('&');
+ }
+ },
+
+ getValue: function( element )
+ {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if ( parameter )
+ return parameter[1];
+ },
+
+ clear: function( element )
+ {
+ $(element).value = '';
+ return element;
+ },
+
+ present: function( element )
+ {
+ return $(element).value != '';
+ },
+
+ activate: function( element )
+ {
+ element = $(element);
+ element.focus();
+ if ( element.select )
+ element.select();
+ return element;
+ },
+
+ disable: function( element )
+ {
+ element = $(element);
+ element.disabled = '';
+ return element;
+ },
+
+ enable: function( element )
+ {
+ element = $(element);
+ element.blur();
+ element.disabled = 'true';
+ return element;
+ }
+}
+
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+ input: function( element )
+ {
+ switch ( element.type.toLowerCase() )
+ {
+ case 'checkbox':
+ case 'radio':
+ return Form.Element.Serializers.inputSelector(element);
+ default:
+ return Form.Element.Serializers.textarea(element);
+ }
+ return false;
+ },
+
+ inputSelector: function( element )
+ {
+ if ( element.checked )
+ return [element.name, element.value];
+ },
+
+ textarea: function( element )
+ {
+ return [element.name, element.value];
+ },
+
+ select: function( element )
+ {
+ return Form.Element.Serializers[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element);
+ },
+
+ selectOne: function( element )
+ {
+ var value = '', opt, index = element.selectedIndex;
+ if ( index >= 0 )
+ {
+ opt = element.options[index];
+ value = opt.value || opt.text;
+ }
+ return [element.name, value];
+ },
+
+ selectMany: function( element )
+ {
+ var value = [];
+ for ( var i = 0; i < element.length; i++ )
+ {
+ var opt = element.options[i];
+ if ( opt.selected )
+ value.push(opt.value || opt.text);
+ }
+ return [element.name, value];
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function()
+{
+}
+Abstract.TimedObserver.prototype = {
+ initialize: function( element, frequency, callback )
+ {
+ this.frequency = frequency;
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ this.registerCallback();
+ },
+
+ registerCallback: function()
+ {
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ onTimerEvent: function()
+ {
+ var value = this.getValue();
+ if ( this.lastValue != value )
+ {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+ getValue: function()
+ {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+ getValue: function()
+ {
+ return Form.serialize(this.element);
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function()
+{
+}
+Abstract.EventObserver.prototype = {
+ initialize: function( element, callback )
+ {
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ if ( this.element.tagName.toLowerCase() == 'form' )
+ this.registerFormCallbacks();
+ else
+ this.registerCallback(this.element);
+ },
+
+ onElementEvent: function()
+ {
+ var value = this.getValue();
+ if ( this.lastValue != value )
+ {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ },
+
+ registerFormCallbacks: function()
+ {
+ var elements = Form.getElements(this.element);
+ for ( var i = 0; i < elements.length; i++ )
+ this.registerCallback(elements[i]);
+ },
+
+ registerCallback: function( element )
+ {
+ if ( element.type )
+ {
+ switch ( element.type.toLowerCase() )
+ {
+ case 'checkbox':
+ case 'radio':
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
+ break;
+ default:
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
+ break;
+ }
+ }
+ }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+ getValue: function()
+ {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+ getValue: function()
+ {
+ return Form.serialize(this.element);
+ }
+});
+if ( !window.Event )
+{
+ var Event = new Object();
+}
+
+Object.extend(Event, {
+ KEY_BACKSPACE: 8,
+ KEY_TAB: 9,
+ KEY_RETURN: 13,
+ KEY_ESC: 27,
+ KEY_LEFT: 37,
+ KEY_UP: 38,
+ KEY_RIGHT: 39,
+ KEY_DOWN: 40,
+ KEY_DELETE: 46,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
+
+ element: function( event )
+ {
+ return event.target || event.srcElement;
+ },
+
+ isLeftClick: function( event )
+ {
+ return (((event.which) && (event.which == 1)) || ((event.button) && (event.button == 1)));
+ },
+
+ pointerX: function( event )
+ {
+ return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
+ },
+
+ pointerY: function( event )
+ {
+ return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
+ },
+
+ stop: function( event )
+ {
+ if ( event.preventDefault )
+ {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ else
+ {
+ event.returnValue = false;
+ event.cancelBubble = true;
+ }
+ },
+
+// find the first node with the given tagName, starting from the
+// node the event was triggered on; traverses the DOM upwards
+ findElement: function( event, tagName )
+ {
+ var element = Event.element(event);
+ while ( element.parentNode && (!element.tagName || (element.tagName.toUpperCase() != tagName.toUpperCase())) )
+ element = element.parentNode;
+ return element;
+ },
+
+ observers: false,
+
+ _observeAndCache: function( element, name, observer, useCapture )
+ {
+ if ( !this.observers ) this.observers = [];
+ if ( element.addEventListener )
+ {
+ this.observers.push([element, name, observer, useCapture]);
+ element.addEventListener(name, observer, useCapture);
+ }
+ else if ( element.attachEvent )
+ {
+ this.observers.push([element, name, observer, useCapture]);
+ element.attachEvent('on' + name, observer);
+ }
+ },
+
+ unloadCache: function()
+ {
+ if ( !Event.observers ) return;
+ for ( var i = 0; i < Event.observers.length; i++ )
+ {
+ Event.stopObserving.apply(this, Event.observers[i]);
+ Event.observers[i][0] = null;
+ }
+ Event.observers = false;
+ },
+
+ observe: function( element, name, observer, useCapture )
+ {
+ element = $(element);
+ useCapture = useCapture || false;
+
+ if ( name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.attachEvent) )
+ name = 'keydown';
+
+ Event._observeAndCache(element, name, observer, useCapture);
+ },
+
+ stopObserving: function( element, name, observer, useCapture )
+ {
+ element = $(element);
+ useCapture = useCapture || false;
+
+ if ( name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.detachEvent) )
+ name = 'keydown';
+
+ if ( element.removeEventListener )
+ {
+ element.removeEventListener(name, observer, useCapture);
+ }
+ else if ( element.detachEvent )
+ {
+ try
+ {
+ element.detachEvent('on' + name, observer);
+ }
+ catch ( e )
+ {
+ }
+ }
+ }
+});
+
+/* prevent memory leaks in IE */
+if ( navigator.appVersion.match(/\bMSIE\b/) )
+ Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+// set to true if needed, warning: firefox performance problems
+// NOT neeeded for page scrolling, only if draggable contained in
+// scrollable elements
+ includeScrollOffsets: false,
+
+// must be called before calling withinIncludingScrolloffset, every time the
+// page is scrolled
+ prepare: function()
+ {
+ this.deltaX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
+ this.deltaY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
+ },
+
+ realOffset: function( element )
+ {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ }
+ while ( element );
+ return [valueL, valueT];
+ },
+
+ cumulativeOffset: function( element )
+ {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ }
+ while ( element );
+ return [valueL, valueT];
+ },
+
+ positionedOffset: function( element )
+ {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if ( element )
+ {
+ p = Element.getStyle(element, 'position');
+ if ( p == 'relative' || p == 'absolute' ) break;
+ }
+ }
+ while ( element );
+ return [valueL, valueT];
+ },
+
+ offsetParent: function( element )
+ {
+ if ( element.offsetParent ) return element.offsetParent;
+ if ( element == document.body ) return element;
+
+ while ( (element = element.parentNode) && element != document.body )
+ if ( Element.getStyle(element, 'position') != 'static' )
+ return element;
+
+ return document.body;
+ },
+
+// caches x/y coordinate pair to use with overlap
+ within: function( element, x, y )
+ {
+ if ( this.includeScrollOffsets )
+ return this.withinIncludingScrolloffsets(element, x, y);
+ this.xcomp = x;
+ this.ycomp = y;
+ this.offset = this.cumulativeOffset(element);
+
+ return (y >= this.offset[1] && y < this.offset[1] + element.offsetHeight && x >= this.offset[0] &&
+ x < this.offset[0] + element.offsetWidth);
+ },
+
+ withinIncludingScrolloffsets: function( element, x, y )
+ {
+ var offsetcache = this.realOffset(element);
+
+ this.xcomp = x + offsetcache[0] - this.deltaX;
+ this.ycomp = y + offsetcache[1] - this.deltaY;
+ this.offset = this.cumulativeOffset(element);
+
+ return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + element.offsetHeight &&
+ this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + element.offsetWidth);
+ },
+
+// within must be called directly before
+ overlap: function( mode, element )
+ {
+ if ( !mode ) return 0;
+ if ( mode == 'vertical' )
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) / element.offsetHeight;
+ if ( mode == 'horizontal' )
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) / element.offsetWidth;
+ },
+
+ page: function( forElement )
+ {
+ var valueT = 0, valueL = 0;
+
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ // Safari fix
+ if ( element.offsetParent == document.body )
+ if ( Element.getStyle(element, 'position') == 'absolute' ) break;
+
+ }
+ while ( element = element.offsetParent );
+
+ element = forElement;
+ do {
+ if ( !window.opera || element.tagName == 'BODY' )
+ {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ }
+ }
+ while ( element = element.parentNode );
+
+ return [valueL, valueT];
+ },
+
+ clone: function( source, target )
+ {
+ var options = Object.extend({
+ setLeft: true,
+ setTop: true,
+ setWidth: true,
+ setHeight: true,
+ offsetTop: 0,
+ offsetLeft: 0
+ }, arguments[2] || {})
+
+ // find page position of source
+ source = $(source);
+ var p = Position.page(source);
+
+ // find coordinate system to use
+ target = $(target);
+ var delta = [0, 0];
+ var parent = null;
+ // delta [0,0] will do fine with position: fixed elements,
+ // position:absolute needs offsetParent deltas
+ if ( Element.getStyle(target, 'position') == 'absolute' )
+ {
+ parent = Position.offsetParent(target);
+ delta = Position.page(parent);
+ }
+
+ // correct by body offsets (fixes Safari)
+ if ( parent == document.body )
+ {
+ delta[0] -= document.body.offsetLeft;
+ delta[1] -= document.body.offsetTop;
+ }
+
+ // set position
+ if ( options.setLeft ) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
+ if ( options.setTop ) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
+ if ( options.setWidth ) target.style.width = source.offsetWidth + 'px';
+ if ( options.setHeight ) target.style.height = source.offsetHeight + 'px';
+ },
+
+ absolutize: function( element )
+ {
+ element = $(element);
+ if ( element.style.position == 'absolute' ) return;
+ Position.prepare();
+
+ var offsets = Position.positionedOffset(element);
+ var top = offsets[1];
+ var left = offsets[0];
+ var width = element.clientWidth;
+ var height = element.clientHeight;
+
+ element._originalLeft = left - parseFloat(element.style.left || 0);
+ element._originalTop = top - parseFloat(element.style.top || 0);
+ element._originalWidth = element.style.width;
+ element._originalHeight = element.style.height;
+
+ element.style.position = 'absolute';
+ element.style.top = top + 'px';
+ ;
+ element.style.left = left + 'px';
+ ;
+ element.style.width = width + 'px';
+ ;
+ element.style.height = height + 'px';
+ ;
+ },
+
+ relativize: function( element )
+ {
+ element = $(element);
+ if ( element.style.position == 'relative' ) return;
+ Position.prepare();
+
+ element.style.position = 'relative';
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.height = element._originalHeight;
+ element.style.width = element._originalWidth;
+ }
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned. For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if ( /Konqueror|Safari|KHTML/.test(navigator.userAgent) )
+{
+ Position.cumulativeOffset = function( element )
+ {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if ( element.offsetParent == document.body )
+ if ( Element.getStyle(element, 'position') == 'absolute' ) break;
+
+ element = element.offsetParent;
+ }
+ while ( element );
+
+ return [valueL, valueT];
+ }
+}
+
+Element.addMethods();
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+// script.aculo.us scriptaculous.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
+
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Scriptaculous = {
+ Version: '1.6.4',
+ require: function( libraryName )
+ {
+ // inserting via DOM fails in Safari 2.0, so brute force approach
+ document.write('<script type="text/javascript" src="' + libraryName + '"></script>');
+ },
+ load: function()
+ {
+ if ( (typeof Prototype == 'undefined') || (typeof Element == 'undefined') ||
+ (typeof Element.Methods == 'undefined') ||
+ parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]) < 1.5 )
+ throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0");
+
+ $A(document.getElementsByTagName("script")).findAll(function( s )
+ {
+ return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+ }).each(function( s )
+ {
+ var path = s.src.replace(/scriptaculous\.js(\?.*)?$/, '');
+ var includes = s.src.match(/\?.*load=([a-z,]*)/);
+ (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(function( include )
+ {
+ Scriptaculous.require(path + include + '.js')
+ });
+ });
+ }
+}
+
+Scriptaculous.load();
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+// script.aculo.us slider.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
+
+// Copyright (c) 2005 Marty Haught, Thomas Fuchs
+//
+// See http://script.aculo.us for more info
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+if ( !Control ) var Control = {};
+Control.Slider = Class.create();
+
+// options:
+// axis: 'vertical', or 'horizontal' (default)
+//
+// callbacks:
+// onChange(value)
+// onSlide(value)
+Control.Slider.prototype = {
+ initialize: function( handle, track, options )
+ {
+ var slider = this;
+
+ if ( handle instanceof Array )
+ {
+ this.handles = handle.collect(function( e )
+ {
+ return $(e)
+ });
+ }
+ else
+ {
+ this.handles = [$(handle)];
+ }
+
+ this.track = $(track);
+ this.options = options || {};
+
+ this.axis = this.options.axis || 'horizontal';
+ this.increment = this.options.increment || 1;
+ this.step = parseInt(this.options.step || '1');
+ this.range = this.options.range || $R(0, 1);
+
+ this.value = 0;
+ // assure backwards compat
+ this.values = this.handles.map(function()
+ {
+ return 0
+ });
+ this.spans = this.options.spans ? this.options.spans.map(function( s )
+ {
+ return $(s)
+ }) : false;
+ this.options.startSpan = $(this.options.startSpan || null);
+ this.options.endSpan = $(this.options.endSpan || null);
+
+ this.restricted = this.options.restricted || false;
+
+ this.maximum = this.options.maximum || this.range.end;
+ this.minimum = this.options.minimum || this.range.start;
+
+ // Will be used to align the handle onto the track, if necessary
+ this.alignX = parseInt(this.options.alignX || '0');
+ this.alignY = parseInt(this.options.alignY || '0');
+
+ this.trackLength = this.maximumOffset() - this.minimumOffset();
+
+ this.handleLength = this.isVertical() ? (this.handles[0].offsetHeight != 0 ? this.handles[0].offsetHeight
+ : this.handles[0].style.height.replace(/px$/, "")) : (this.handles[0].offsetWidth != 0
+ ? this.handles[0].offsetWidth : this.handles[0].style.width.replace(/px$/, ""));
+
+ this.active = false;
+ this.dragging = false;
+ this.disabled = false;
+
+ if ( this.options.disabled ) this.setDisabled();
+
+ // Allowed values array
+ this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
+ if ( this.allowedValues )
+ {
+ this.minimum = this.allowedValues.min();
+ this.maximum = this.allowedValues.max();
+ }
+
+ this.eventMouseDown = this.startDrag.bindAsEventListener(this);
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
+ this.eventMouseMove = this.update.bindAsEventListener(this);
+
+ // Initialize handles in reverse (make sure first handle is active)
+ this.handles.each(function( h, i )
+ {
+ i = slider.handles.length - 1 - i;
+ slider.setValue(parseFloat((slider.options.sliderValue instanceof Array ? slider.options.sliderValue[i]
+ : slider.options.sliderValue) || slider.range.start), i);
+ Element.makePositioned(h);
+ // fix IE
+ Event.observe(h, "mousedown", slider.eventMouseDown);
+ });
+
+ Event.observe(this.track, "mousedown", this.eventMouseDown);
+ Event.observe(document, "mouseup", this.eventMouseUp);
+ Event.observe(document, "mousemove", this.eventMouseMove);
+
+ this.initialized = true;
+ },
+ dispose: function()
+ {
+ var slider = this;
+ Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
+ Event.stopObserving(document, "mouseup", this.eventMouseUp);
+ Event.stopObserving(document, "mousemove", this.eventMouseMove);
+ this.handles.each(function( h )
+ {
+ Event.stopObserving(h, "mousedown", slider.eventMouseDown);
+ });
+ },
+ setDisabled: function()
+ {
+ this.disabled = true;
+ },
+ setEnabled: function()
+ {
+ this.disabled = false;
+ },
+ getNearestValue: function( value )
+ {
+ if ( this.allowedValues )
+ {
+ if ( value >= this.allowedValues.max() ) return(this.allowedValues.max());
+ if ( value <= this.allowedValues.min() ) return(this.allowedValues.min());
+
+ var offset = Math.abs(this.allowedValues[0] - value);
+ var newValue = this.allowedValues[0];
+ this.allowedValues.each(function( v )
+ {
+ var currentOffset = Math.abs(v - value);
+ if ( currentOffset <= offset )
+ {
+ newValue = v;
+ offset = currentOffset;
+ }
+ });
+ return newValue;
+ }
+ if ( value > this.range.end ) return this.range.end;
+ if ( value < this.range.start ) return this.range.start;
+ return value;
+ },
+ setValue: function( sliderValue, handleIdx )
+ {
+ if ( !this.active )
+ {
+ this.activeHandleIdx = handleIdx || 0;
+ this.activeHandle = this.handles[this.activeHandleIdx];
+ this.updateStyles();
+ }
+ handleIdx = handleIdx || this.activeHandleIdx || 0;
+ if ( this.initialized && this.restricted )
+ {
+ if ( (handleIdx > 0) && (sliderValue < this.values[handleIdx - 1]) )
+ sliderValue = this.values[handleIdx - 1];
+ if ( (handleIdx < (this.handles.length - 1)) && (sliderValue > this.values[handleIdx + 1]) )
+ sliderValue = this.values[handleIdx + 1];
+ }
+ sliderValue = this.getNearestValue(sliderValue);
+ this.values[handleIdx] = sliderValue;
+ this.value = this.values[0];
+ // assure backwards compat
+
+ this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = this.translateToPx(sliderValue);
+
+ this.drawSpans();
+ if ( !this.dragging || !this.event ) this.updateFinished();
+ },
+ setValueBy: function( delta, handleIdx )
+ {
+ this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, handleIdx || this.activeHandleIdx ||
+ 0);
+ },
+ translateToPx: function( value )
+ {
+ return Math.round(((this.trackLength - this.handleLength) / (this.range.end - this.range.start)) *
+ (value - this.range.start)) + "px";
+ },
+ translateToValue: function( offset )
+ {
+ return ((offset / (this.trackLength - this.handleLength) * (this.range.end - this.range.start)) +
+ this.range.start);
+ },
+ getRange: function( range )
+ {
+ var v = this.values.sortBy(Prototype.K);
+ range = range || 0;
+ return $R(v[range], v[range + 1]);
+ },
+ minimumOffset: function()
+ {
+ return(this.isVertical() ? this.alignY : this.alignX);
+ },
+ maximumOffset: function()
+ {
+ return(this.isVertical() ? (this.track.offsetHeight != 0 ? this.track.offsetHeight
+ : this.track.style.height.replace(/px$/, "")) - this.alignY : (this.track.offsetWidth != 0
+ ? this.track.offsetWidth : this.track.style.width.replace(/px$/, "")) - this.alignY);
+ },
+ isVertical: function()
+ {
+ return (this.axis == 'vertical');
+ },
+ drawSpans: function()
+ {
+ var slider = this;
+ if ( this.spans )
+ $R(0, this.spans.length - 1).each(function( r )
+ {
+ slider.setSpan(slider.spans[r], slider.getRange(r))
+ });
+ if ( this.options.startSpan )
+ this.setSpan(this.options.startSpan, $R(0, this.values.length > 1 ? this.getRange(0).min() : this.value));
+ if ( this.options.endSpan )
+ this.setSpan(this.options.endSpan, $R(this.values.length > 1 ? this.getRange(this.spans.length - 1).max()
+ : this.value, this.maximum));
+ },
+ setSpan: function( span, range )
+ {
+ if ( this.isVertical() )
+ {
+ span.style.top = this.translateToPx(range.start);
+ span.style.height = this.translateToPx(range.end - range.start + this.range.start);
+ }
+ else
+ {
+ span.style.left = this.translateToPx(range.start);
+ span.style.width = this.translateToPx(range.end - range.start + this.range.start);
+ }
+ },
+ updateStyles: function()
+ {
+ this.handles.each(function( h )
+ {
+ Element.removeClassName(h, 'selected')
+ });
+ Element.addClassName(this.activeHandle, 'selected');
+ },
+ startDrag: function( event )
+ {
+ if ( Event.isLeftClick(event) )
+ {
+ if ( !this.disabled )
+ {
+ this.active = true;
+
+ var handle = Event.element(event);
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var track = handle;
+ if ( track == this.track )
+ {
+ var offsets = Position.cumulativeOffset(this.track);
+ this.event = event;
+ this.setValue(this.translateToValue((this.isVertical() ? pointer[1] - offsets[1] : pointer[0] -
+ offsets[0]) -
+ (this.handleLength / 2)));
+ var offsets = Position.cumulativeOffset(this.activeHandle);
+ this.offsetX = (pointer[0] - offsets[0]);
+ this.offsetY = (pointer[1] - offsets[1]);
+ }
+ else
+ {
+ // find the handle (prevents issues with Safari)
+ while ( (this.handles.indexOf(handle) == -1) && handle.parentNode )
+ handle = handle.parentNode;
+
+ this.activeHandle = handle;
+ this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+ this.updateStyles();
+
+ var offsets = Position.cumulativeOffset(this.activeHandle);
+ this.offsetX = (pointer[0] - offsets[0]);
+ this.offsetY = (pointer[1] - offsets[1]);
+ }
+ }
+ Event.stop(event);
+ }
+ },
+ update: function( event )
+ {
+ if ( this.active )
+ {
+ if ( !this.dragging ) this.dragging = true;
+ this.draw(event);
+ // fix AppleWebKit rendering
+ if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) window.scrollBy(0, 0);
+ Event.stop(event);
+ }
+ },
+ draw: function( event )
+ {
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var offsets = Position.cumulativeOffset(this.track);
+ pointer[0] -= this.offsetX + offsets[0];
+ pointer[1] -= this.offsetY + offsets[1];
+ this.event = event;
+ this.setValue(this.translateToValue(this.isVertical() ? pointer[1] : pointer[0]));
+ if ( this.initialized && this.options.onSlide )
+ this.options.onSlide(this.values.length > 1 ? this.values : this.value, this);
+ },
+ endDrag: function( event )
+ {
+ if ( this.active && this.dragging )
+ {
+ this.finishDrag(event, true);
+ Event.stop(event);
+ }
+ this.active = false;
+ this.dragging = false;
+ },
+ finishDrag: function( event, success )
+ {
+ this.active = false;
+ this.dragging = false;
+ this.updateFinished();
+ },
+ updateFinished: function()
+ {
+ if ( this.initialized && this.options.onChange )
+ this.options.onChange(this.values.length > 1 ? this.values : this.value, this);
+ this.event = null;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+// script.aculo.us unittest.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
+
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005 Jon Tirsen (http://www.tirsen.com)
+// (c) 2005 Michael Schuerig (http://www.schuerig.de/michael/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// experimental, Firefox-only
+Event.simulateMouse = function( element, eventName )
+{
+ var options = Object.extend({
+ pointerX: 0,
+ pointerY: 0,
+ buttons: 0
+ }, arguments[2] || {});
+ var oEvent = document.createEvent("MouseEvents");
+ oEvent.initMouseEvent(eventName, true, true, document.defaultView, options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, false, false, false, false, 0, $(element));
+
+ if ( this.mark ) Element.remove(this.mark);
+ this.mark = document.createElement('div');
+ this.mark.appendChild(document.createTextNode(" "));
+ document.body.appendChild(this.mark);
+ this.mark.style.position = 'absolute';
+ this.mark.style.top = options.pointerY + "px";
+ this.mark.style.left = options.pointerX + "px";
+ this.mark.style.width = "5px";
+ this.mark.style.height = "5px;";
+ this.mark.style.borderTop = "1px solid red;"
+ this.mark.style.borderLeft = "1px solid red;"
+
+ if ( this.step )
+ alert('[' + new Date().getTime().toString() + '] ' + eventName + '/' + Test.Unit.inspect(options));
+
+ $(element).dispatchEvent(oEvent);
+};
+
+// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
+// You need to downgrade to 1.0.4 for now to get this working
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
+Event.simulateKey = function( element, eventName )
+{
+ var options = Object.extend({
+ ctrlKey: false,
+ altKey: false,
+ shiftKey: false,
+ metaKey: false,
+ keyCode: 0,
+ charCode: 0
+ }, arguments[2] || {});
+
+ var oEvent = document.createEvent("KeyEvents");
+ oEvent.initKeyEvent(eventName, true, true, window, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.keyCode, options.charCode);
+ $(element).dispatchEvent(oEvent);
+};
+
+Event.simulateKeys = function( element, command )
+{
+ for ( var i = 0; i < command.length; i++ )
+ {
+ Event.simulateKey(element, 'keypress', {charCode:command.charCodeAt(i)});
+ }
+};
+
+var Test = {}
+Test.Unit = {};
+
+// security exception workaround
+Test.Unit.inspect = Object.inspect;
+
+Test.Unit.Logger = Class.create();
+Test.Unit.Logger.prototype = {
+ initialize: function( log )
+ {
+ this.log = $(log);
+ if ( this.log )
+ {
+ this._createLogTable();
+ }
+ },
+ start: function( testName )
+ {
+ if ( !this.log ) return;
+ this.testName = testName;
+ this.lastLogLine = document.createElement('tr');
+ this.statusCell = document.createElement('td');
+ this.nameCell = document.createElement('td');
+ this.nameCell.appendChild(document.createTextNode(testName));
+ this.messageCell = document.createElement('td');
+ this.lastLogLine.appendChild(this.statusCell);
+ this.lastLogLine.appendChild(this.nameCell);
+ this.lastLogLine.appendChild(this.messageCell);
+ this.loglines.appendChild(this.lastLogLine);
+ },
+ finish: function( status, summary )
+ {
+ if ( !this.log ) return;
+ this.lastLogLine.className = status;
+ this.statusCell.innerHTML = status;
+ this.messageCell.innerHTML = this._toHTML(summary);
+ },
+ message: function( message )
+ {
+ if ( !this.log ) return;
+ this.messageCell.innerHTML = this._toHTML(message);
+ },
+ summary: function( summary )
+ {
+ if ( !this.log ) return;
+ this.logsummary.innerHTML = this._toHTML(summary);
+ },
+ _createLogTable: function()
+ {
+ this.log.innerHTML = '<div id="logsummary"></div>' + '<table id="logtable">' +
+ '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
+ '<tbody id="loglines"></tbody>' + '</table>';
+ this.logsummary = $('logsummary')
+ this.loglines = $('loglines');
+ },
+ _toHTML: function( txt )
+ {
+ return txt.escapeHTML().replace(/\n/g, "<br/>");
+ }
+}
+
+Test.Unit.Runner = Class.create();
+Test.Unit.Runner.prototype = {
+ initialize: function( testcases )
+ {
+ this.options = Object.extend({
+ testLog: 'testlog'
+ }, arguments[1] || {});
+ this.options.resultsURL = this.parseResultsURLQueryParameter();
+ if ( this.options.testLog )
+ {
+ this.options.testLog = $(this.options.testLog) || null;
+ }
+ if ( this.options.tests )
+ {
+ this.tests = [];
+ for ( var i = 0; i < this.options.tests.length; i++ )
+ {
+ if ( /^test/.test(this.options.tests[i]) )
+ {
+ this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
+ }
+ }
+ }
+ else
+ {
+ if ( this.options.test )
+ {
+ this.tests =
+ [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
+ }
+ else
+ {
+ this.tests = [];
+ for ( var testcase in testcases )
+ {
+ if ( /^test/.test(testcase) )
+ {
+ this.tests.push(new Test.Unit.Testcase(this.options.context ? ' -> ' +
+ this.options.titles[testcase]
+ : testcase, testcases[testcase], testcases["setup"], testcases["teardown"]));
+ }
+ }
+ }
+ }
+ this.currentTest = 0;
+ this.logger = new Test.Unit.Logger(this.options.testLog);
+ setTimeout(this.runTests.bind(this), 1000);
+ },
+ parseResultsURLQueryParameter: function()
+ {
+ return window.location.search.parseQuery()["resultsURL"];
+ },
+// Returns:
+// "ERROR" if there was an error,
+// "FAILURE" if there was a failure, or
+// "SUCCESS" if there was neither
+ getResult: function()
+ {
+ var hasFailure = false;
+ for ( var i = 0; i < this.tests.length; i++ )
+ {
+ if ( this.tests[i].errors > 0 )
+ {
+ return "ERROR";
+ }
+ if ( this.tests[i].failures > 0 )
+ {
+ hasFailure = true;
+ }
+ }
+ if ( hasFailure )
+ {
+ return "FAILURE";
+ }
+ else
+ {
+ return "SUCCESS";
+ }
+ },
+ postResults: function()
+ {
+ if ( this.options.resultsURL )
+ {
+ new Ajax.Request(this.options.resultsURL, { method: 'get', parameters: 'result=' +
+ this.getResult(), asynchronous: false });
+ }
+ },
+ runTests: function()
+ {
+ var test = this.tests[this.currentTest];
+ if ( !test )
+ {
+ // finished!
+ this.postResults();
+ this.logger.summary(this.summary());
+ return;
+ }
+ if ( !test.isWaiting )
+ {
+ this.logger.start(test.name);
+ }
+ test.run();
+ if ( test.isWaiting )
+ {
+ this.logger.message("Waiting for " + test.timeToWait + "ms");
+ setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
+ }
+ else
+ {
+ this.logger.finish(test.status(), test.summary());
+ this.currentTest++;
+ // tail recursive, hopefully the browser will skip the stackframe
+ this.runTests();
+ }
+ },
+ summary: function()
+ {
+ var assertions = 0;
+ var failures = 0;
+ var errors = 0;
+ var messages = [];
+ for ( var i = 0; i < this.tests.length; i++ )
+ {
+ assertions += this.tests[i].assertions;
+ failures += this.tests[i].failures;
+ errors += this.tests[i].errors;
+ }
+ return (
+ (this.options.context ? this.options.context + ': ' : '') + this.tests.length + " tests, " + assertions +
+ " assertions, " + failures + " failures, " + errors + " errors");
+ }
+}
+
+Test.Unit.Assertions = Class.create();
+Test.Unit.Assertions.prototype = {
+ initialize: function()
+ {
+ this.assertions = 0;
+ this.failures = 0;
+ this.errors = 0;
+ this.messages = [];
+ },
+ summary: function()
+ {
+ return (
+ this.assertions + " assertions, " + this.failures + " failures, " + this.errors + " errors" + "\n" +
+ this.messages.join("\n"));
+ },
+ pass: function()
+ {
+ this.assertions++;
+ },
+ fail: function( message )
+ {
+ this.failures++;
+ this.messages.push("Failure: " + message);
+ },
+ info: function( message )
+ {
+ this.messages.push("Info: " + message);
+ },
+ error: function( error )
+ {
+ this.errors++;
+ this.messages.push(error.name + ": " + error.message + "(" + Test.Unit.inspect(error) + ")");
+ },
+ status: function()
+ {
+ if ( this.failures > 0 ) return 'failed';
+ if ( this.errors > 0 ) return 'error';
+ return 'passed';
+ },
+ assert: function( expression )
+ {
+ var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
+ try
+ {
+ expression ? this.pass() : this.fail(message);
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertEqual: function( expected, actual )
+ {
+ var message = arguments[2] || "assertEqual";
+ try
+ {
+ (expected == actual) ? this.pass() : this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+ '", actual "' + Test.Unit.inspect(actual) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertEnumEqual: function( expected, actual )
+ {
+ var message = arguments[2] || "assertEnumEqual";
+ try
+ {
+ $A(expected).length == $A(actual).length && expected.zip(actual).all(function( pair )
+ {
+ return pair[0] == pair[1]
+ }) ? this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + ', actual ' +
+ Test.Unit.inspect(actual));
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertNotEqual: function( expected, actual )
+ {
+ var message = arguments[2] || "assertNotEqual";
+ try
+ {
+ (expected != actual) ? this.pass() : this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertIdentical: function( expected, actual )
+ {
+ var message = arguments[2] || "assertIdentical";
+ try
+ {
+ (expected === actual) ? this.pass() : this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+ '", actual "' + Test.Unit.inspect(actual) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertNotIdentical: function( expected, actual )
+ {
+ var message = arguments[2] || "assertNotIdentical";
+ try
+ {
+ !(expected === actual) ? this.pass() : this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+ '", actual "' + Test.Unit.inspect(actual) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertNull: function( obj )
+ {
+ var message = arguments[1] || 'assertNull'
+ try
+ {
+ (obj == null) ? this.pass() : this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertMatch: function( expected, actual )
+ {
+ var message = arguments[2] || 'assertMatch';
+ var regex = new RegExp(expected);
+ try
+ {
+ (regex.exec(actual)) ? this.pass() : this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) +
+ ' did not match: ' + Test.Unit.inspect(actual) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertHidden: function( element )
+ {
+ var message = arguments[1] || 'assertHidden';
+ this.assertEqual("none", element.style.display, message);
+ },
+ assertNotNull: function( object )
+ {
+ var message = arguments[1] || 'assertNotNull';
+ this.assert(object != null, message);
+ },
+ assertType: function( expected, actual )
+ {
+ var message = arguments[2] || 'assertType';
+ try
+ {
+ (actual.constructor == expected) ? this.pass() : this.fail(message + ': expected "' +
+ Test.Unit.inspect(expected) + '", actual "' +
+ (actual.constructor) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertNotOfType: function( expected, actual )
+ {
+ var message = arguments[2] || 'assertNotOfType';
+ try
+ {
+ (actual.constructor != expected) ? this.pass() : this.fail(message + ': expected "' +
+ Test.Unit.inspect(expected) + '", actual "' +
+ (actual.constructor) + '"');
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertInstanceOf: function( expected, actual )
+ {
+ var message = arguments[2] || 'assertInstanceOf';
+ try
+ {
+ (actual instanceof expected) ? this.pass() : this.fail(message +
+ ": object was not an instance of the expected type");
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertNotInstanceOf: function( expected, actual )
+ {
+ var message = arguments[2] || 'assertNotInstanceOf';
+ try
+ {
+ !(actual instanceof expected) ? this.pass() : this.fail(message +
+ ": object was an instance of the not expected type");
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertRespondsTo: function( method, obj )
+ {
+ var message = arguments[2] || 'assertRespondsTo';
+ try
+ {
+ (obj[method] && typeof obj[method] == 'function') ? this.pass() : this.fail(message +
+ ": object doesn't respond to [" +
+ method + "]");
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertReturnsTrue: function( method, obj )
+ {
+ var message = arguments[2] || 'assertReturnsTrue';
+ try
+ {
+ var m = obj[method];
+ if ( !m ) m = obj['is' + method.charAt(0).toUpperCase() + method.slice(1)];
+ m() ? this.pass() : this.fail(message + ": method returned false");
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertReturnsFalse: function( method, obj )
+ {
+ var message = arguments[2] || 'assertReturnsFalse';
+ try
+ {
+ var m = obj[method];
+ if ( !m ) m = obj['is' + method.charAt(0).toUpperCase() + method.slice(1)];
+ !m() ? this.pass() : this.fail(message + ": method returned true");
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ },
+ assertRaise: function( exceptionName, method )
+ {
+ var message = arguments[2] || 'assertRaise';
+ try
+ {
+ method();
+ this.fail(message + ": exception expected but none was raised");
+ }
+ catch( e )
+ {
+ (e.name == exceptionName) ? this.pass() : this.error(e);
+ }
+ },
+ assertElementsMatch: function()
+ {
+ var expressions = $A(arguments), elements = $A(expressions.shift());
+ if ( elements.length != expressions.length )
+ {
+ this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length +
+ ' expressions');
+ return false;
+ }
+ elements.zip(expressions).all(function( pair, index )
+ {
+ var element = $(pair.first()), expression = pair.last();
+ if ( element.match(expression) ) return true;
+ this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' +
+ element.inspect());
+ }.bind(this)) && this.pass();
+ },
+ assertElementMatches: function( element, expression )
+ {
+ this.assertElementsMatch([element], expression);
+ },
+ benchmark: function( operation, iterations )
+ {
+ var startAt = new Date();
+ (iterations || 1).times(operation);
+ var timeTaken = ((new Date()) - startAt);
+ this.info((arguments[2] || 'Operation') + ' finished ' + iterations + ' iterations in ' + (timeTaken / 1000) +
+ 's');
+ return timeTaken;
+ },
+ _isVisible: function( element )
+ {
+ element = $(element);
+ if ( !element.parentNode ) return true;
+ this.assertNotNull(element);
+ if ( element.style && Element.getStyle(element, 'display') == 'none' )
+ return false;
+
+ return this._isVisible(element.parentNode);
+ },
+ assertNotVisible: function( element )
+ {
+ this.assert(!this._isVisible(element), Test.Unit.inspect(element) +
+ " was not hidden and didn't have a hidden parent either. " +
+ ("" || arguments[1]));
+ },
+ assertVisible: function( element )
+ {
+ this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
+ },
+ benchmark: function( operation, iterations )
+ {
+ var startAt = new Date();
+ (iterations || 1).times(operation);
+ var timeTaken = ((new Date()) - startAt);
+ this.info((arguments[2] || 'Operation') + ' finished ' + iterations + ' iterations in ' + (timeTaken / 1000) +
+ 's');
+ return timeTaken;
+ }
+}
+
+Test.Unit.Testcase = Class.create();
+Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
+ initialize: function( name, test, setup, teardown )
+ {
+ Test.Unit.Assertions.prototype.initialize.bind(this)();
+ this.name = name;
+
+ if ( typeof test == 'string' )
+ {
+ test = test.gsub(/(\.should[^\(]+\()/, '#{0}this,');
+ test = test.gsub(/(\.should[^\(]+)\(this,\)/, '#{1}(this)');
+ this.test = function()
+ {
+ eval('with(this){' + test + '}');
+ }
+ }
+ else
+ {
+ this.test = test || function()
+ {
+ };
+ }
+
+ this.setup = setup || function()
+ {
+ };
+ this.teardown = teardown || function()
+ {
+ };
+ this.isWaiting = false;
+ this.timeToWait = 1000;
+ },
+ wait: function( time, nextPart )
+ {
+ this.isWaiting = true;
+ this.test = nextPart;
+ this.timeToWait = time;
+ },
+ run: function()
+ {
+ try
+ {
+ try
+ {
+ if ( !this.isWaiting ) this.setup.bind(this)();
+ this.isWaiting = false;
+ this.test.bind(this)();
+ }
+ finally
+ {
+ if ( !this.isWaiting )
+ {
+ this.teardown.bind(this)();
+ }
+ }
+ }
+ catch( e )
+ {
+ this.error(e);
+ }
+ }
+});
+
+// *EXPERIMENTAL* BDD-style testing to please non-technical folk
+// This draws many ideas from RSpec http://rspec.rubyforge.org/
+
+Test.setupBDDExtensionMethods = function()
+{
+ var METHODMAP = {
+ shouldEqual: 'assertEqual',
+ shouldNotEqual: 'assertNotEqual',
+ shouldEqualEnum: 'assertEnumEqual',
+ shouldBeA: 'assertType',
+ shouldNotBeA: 'assertNotOfType',
+ shouldBeAn: 'assertType',
+ shouldNotBeAn: 'assertNotOfType',
+ shouldBeNull: 'assertNull',
+ shouldNotBeNull: 'assertNotNull',
+
+ shouldBe: 'assertReturnsTrue',
+ shouldNotBe: 'assertReturnsFalse',
+ shouldRespondTo: 'assertRespondsTo'
+ };
+ Test.BDDMethods = {};
+ for ( m in METHODMAP )
+ {
+ Test.BDDMethods[m] =
+ eval('function(){' + 'var args = $A(arguments);' + 'var scope = args.shift();' + 'scope.' + METHODMAP[m] +
+ '.apply(scope,(args || []).concat([this])); }');
+ }
+ [Array.prototype, String.prototype, Number.prototype].each(function( p )
+ {
+ Object.extend(p, Test.BDDMethods)
+ });
+}
+
+Test.context = function( name, spec, log )
+{
+ Test.setupBDDExtensionMethods();
+
+ var compiledSpec = {};
+ var titles = {};
+ for ( specName in spec )
+ {
+ switch ( specName )
+ {
+ case "setup":
+ case "teardown":
+ compiledSpec[specName] = spec[specName];
+ break;
+ default:
+ var testName = 'test' + specName.gsub(/\s+/, '-').camelize();
+ var body = spec[specName].toString().split('\n').slice(1);
+ if ( /^\{/.test(body[0]) ) body = body.slice(1);
+ body.pop();
+ body = body.map(function( statement )
+ {
+ return statement.strip()
+ });
+ compiledSpec[testName] = body.join('\n');
+ titles[testName] = specName;
+ }
+ }
+ new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
+};
\ No newline at end of file
--- /dev/null
+<@ww.iterator value="parameters.list">
+ <#if parameters.listKey?exists>
+ <#assign itemKey = stack.findValue(parameters.listKey)/>
+ <#else>
+ <#assign itemKey = stack.findValue('top')/>
+ </#if>
+ <#if parameters.listValue?exists>
+ <#assign itemValue = stack.findString(parameters.listValue)/>
+ <#else>
+ <#assign itemValue = stack.findString('top')/>
+ </#if>
+<input type="checkbox" name="${parameters.name?html}" id="${parameters.id?html}${itemKey?html}"<#rt/>
+<#if tag.contains(parameters.nameValue, itemKey)>
+ checked="checked"<#rt/>
+</#if>
+<#if itemKey?exists>
+ value="${itemKey?html}"<#rt/>
+</#if>
+<#if parameters.disabled?default(false)>
+ disabled="disabled"<#rt/>
+</#if>
+<#if parameters.tabindex?exists>
+ tabindex="${parameters.tabindex?html}"<#rt/>
+</#if>
+<#if parameters.cssClass?exists>
+ class="${parameters.cssClass?html}"<#rt/>
+</#if>
+<#if parameters.cssStyle?exists>
+ style="${parameters.cssStyle?html}"<#rt/>
+</#if>
+<#if parameters.title?exists>
+ title="${parameters.title?html}"<#rt/>
+</#if>
+<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
+/><#rt/>
+<label for="${parameters.id?html}${itemKey?html}"><#rt/>
+ ${itemValue}<#t/>
+</label><br/>
+</@ww.iterator>
--- /dev/null
+<@ww.iterator value="parameters.list">
+ <#if parameters.listKey?exists>
+ <#assign itemKey = stack.findValue(parameters.listKey)/>
+ <#else>
+ <#assign itemKey = stack.findValue('top')/>
+ </#if>
+ <#if parameters.listValue?exists>
+ <#assign itemValue = stack.findString(parameters.listValue)/>
+ <#else>
+ <#assign itemValue = stack.findString('top')/>
+ </#if>
+<input type="radio" name="${parameters.name?html}" id="${parameters.id?html}${itemKey?html}"<#rt/>
+<#if tag.contains(parameters.nameValue, itemKey)>
+ checked="checked"<#rt/>
+</#if>
+<#if itemKey?exists>
+ value="${itemKey?html}"<#rt/>
+</#if>
+<#if parameters.disabled?default(false)>
+ disabled="disabled"<#rt/>
+</#if>
+<#if parameters.tabindex?exists>
+ tabindex="${parameters.tabindex?html}"<#rt/>
+</#if>
+<#if parameters.cssClass?exists>
+ class="${parameters.cssClass?html}"<#rt/>
+</#if>
+<#if parameters.cssStyle?exists>
+ style="${parameters.cssStyle?html}"<#rt/>
+</#if>
+<#if parameters.title?exists>
+ title="${parameters.title?html}"<#rt/>
+</#if>
+<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
+/><#rt/>
+<label for="${parameters.id?html}${itemKey?html}"><#rt/>
+ ${itemValue}<#t/>
+</label><br/>
+</@ww.iterator>
--- /dev/null
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+parent = xhtml
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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.
+ -->
+
+<plexus>
+ <components>
+ <!--
+ | Logger manager
+ -->
+ <component>
+ <role>org.codehaus.plexus.logging.LoggerManager</role>
+ <implementation>org.codehaus.plexus.logging.log4j.Log4JLoggerManager</implementation>
+ <lifecycle-handler>basic</lifecycle-handler>
+
+ <configuration>
+ <threshold>DEBUG</threshold>
+ <default-appender>console</default-appender>
+ <appenders>
+ <appender>
+ <id>console</id>
+ <threshold>DEBUG</threshold>
+ <type>org.apache.log4j.ConsoleAppender</type>
+ <!-- <conversion-pattern>%d [%t] %-5p %-30c{1} - %m%n</conversion-pattern> -->
+ <conversion-pattern>%r [%t] %-5p %c %x - %m%n</conversion-pattern>
+ </appender>
+ </appenders>
+ <levels>
+ <!-- Help identify bugs during testing -->
+ <level>
+ <hierarchy>org.apache.maven</hierarchy>
+ <level>DEBUG</level>
+ </level>
+ <level>
+ <hierarchy>org.codehaus.plexus.security</hierarchy>
+ <level>DEBUG</level>
+ </level>
+ <!-- squelch noisy objects (for now) -->
+ <level>
+ <hierarchy>org.codehaus.plexus.mailsender.MailSender</hierarchy>
+ <level>INFO</level>
+ </level>
+ <level>
+ <hierarchy>org.quartz</hierarchy>
+ <level>INFO</level>
+ </level>
+ <level>
+ <hierarchy>org.apache.jasper</hierarchy>
+ <level>INFO</level>
+ </level>
+ <level>
+ <hierarchy>com.opensymphony.xwork</hierarchy>
+ <level>DEBUG</level>
+ </level>
+ <level>
+ <hierarchy>com.opensymphony.webwork</hierarchy>
+ <level>DEBUG</level>
+ </level>
+ <level>
+ <hierarchy>org.codehaus.plexus.PlexusContainer</hierarchy>
+ <level>INFO</level>
+ </level>
+ <level>
+ <hierarchy>JPOX</hierarchy>
+ <level>WARN</level>
+ </level>
+ <level>
+ <hierarchy>freemarker</hierarchy>
+ <level>WARN</level>
+ </level>
+ <level>
+ <hierarchy>freemarker</hierarchy>
+ <level>WARN</level>
+ </level>
+ </levels>
+ </configuration>
+ </component>
+
+
+ <component>
+ <role>org.codehaus.plexus.jdo.JdoFactory</role>
+ <role-hint>users</role-hint>
+ <implementation>org.codehaus.plexus.jdo.DefaultConfigurableJdoFactory</implementation>
+ <configuration>
+
+ <!-- HSQLDB Configuration -->
+ <!--
+ NOTE: NO NOT USE THIS CONFIGURATION FOR A PRODUCTION SYSTEM.
+ HSQLDB keeps all data in memory at all times.
+
+ NOTE: JPOX 1.1.1 won't create the tables on start
+ http://www.jpox.org/servlet/jira/browse/CORE-2946
+ -->
+
+ <!--
+ <driverName>org.hsqldb.jdbcDriver</driverName>
+ <url>jdbc:hsqldb:mem:test</url>
+ <userName>sa</userName>
+ <password></password>
+ -->
+
+ <!-- Apache Derby Configuration -->
+ <driverName>org.apache.derby.jdbc.EmbeddedDriver</driverName>
+ <url>jdbc:derby:${basedir}/target/repoaccess/database;create=true</url>
+ <userName>sa</userName>
+ <password></password>
+
+ <!-- MySql Configuration -->
+ <!--
+ <driverName>com.mysql.jdbc.Driver</driverName>
+ <url>jdbc:mysql://localhost/archiva</url>
+ <userName>archiva</userName>
+ <password>archiva</password>
+ -->
+
+ <!-- Postgresql Configuration -->
+ <!--
+ <driverName>org.postgresql.Driver</driverName>
+ <url>jdbc:postgresql://localhost/continuum</url>
+ <userName>username</userName>
+ <password></password>
+ -->
+
+ <!-- JPOX and JDO configuration -->
+ <persistenceManagerFactoryClass>org.jpox.PersistenceManagerFactoryImpl</persistenceManagerFactoryClass>
+ <otherProperties>
+ <property>
+ <name>javax.jdo.PersistenceManagerFactoryClass</name>
+ <value>org.jpox.PersistenceManagerFactoryImpl</value>
+ </property>
+ <property>
+ <name>org.jpox.autoCreateSchema</name>
+ <value>true</value>
+ </property>
+ <property>
+ <name>org.jpox.autoStartMechanism</name>
+ <value>SchemaTable</value>
+ </property>
+ <property>
+ <name>org.jpox.autoStartMechanismMode</name>
+ <value>Ignored</value>
+ </property>
+ <property>
+ <name>org.jpox.validateTables</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.validateConstraints</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>org.jpox.transactionIsolation</name>
+ <value>READ_UNCOMMITTED</value>
+ </property>
+ <property>
+ <name>org.jpox.poid.transactionIsolation</name>
+ <value>READ_UNCOMMITTED</value>
+ </property>
+ <property>
+ <name>org.jpox.rdbms.dateTimezone</name>
+ <value>JDK_DEFAULT_TIMEZONE</value>
+ </property>
+ </otherProperties>
+ </configuration>
+ </component>
+
+ </components>
+</plexus>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.maven.archiva</groupId>
- <artifactId>archiva</artifactId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>archiva-webapp</artifactId>
- <packaging>war</packaging>
- <name>Archiva Web Application</name>
- <dependencies>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.4</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jsp-api</artifactId>
- <version>2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>opensymphony</groupId>
- <artifactId>sitemesh</artifactId>
- <version>2.2.1</version>
- </dependency>
- <dependency>
- <groupId>taglibs</groupId>
- <artifactId>standard</artifactId>
- <version>1.1.2</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jstl</artifactId>
- <version>1.1.2</version>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.shared</groupId>
- <artifactId>maven-app-configuration-model</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.shared</groupId>
- <artifactId>maven-app-configuration-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-slf4j-logging</artifactId>
- <version>1.1-alpha-1-SNAPSHOT</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.2</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.0.4</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.2</version>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.wagon</groupId>
- <artifactId>wagon-http-lightweight</artifactId>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.wagon</groupId>
- <artifactId>wagon-file</artifactId>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>opensymphony</groupId>
- <artifactId>webwork</artifactId>
- <version>2.2.4</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus.registry</groupId>
- <artifactId>plexus-registry-api</artifactId>
- <version>1.0-alpha-2-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus.registry</groupId>
- <artifactId>plexus-registry-commons</artifactId>
- <version>1.0-alpha-2-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-component-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-container-default</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.archiva</groupId>
- <artifactId>archiva-proxy</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.archiva</groupId>
- <artifactId>archiva-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.archiva</groupId>
- <artifactId>archiva-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.archiva</groupId>
- <artifactId>archiva-security</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.archiva</groupId>
- <artifactId>archiva-applet</artifactId>
- <!-- TODO: actually, just exclude from WAR plugin -->
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.maven</groupId>
- <artifactId>maven-project</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.shared</groupId>
- <artifactId>maven-dependency-tree</artifactId>
- <version>1.0-alpha-2</version>
- </dependency>
- <!-- Plexus Security Dependencies -->
- <dependency>
- <groupId>org.codehaus.plexus.security</groupId>
- <artifactId>plexus-security-ui-web</artifactId>
- <type>war</type>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus.security</groupId>
- <artifactId>plexus-security-ui-web-taglib</artifactId>
- </dependency>
- <!-- Other dependencies -->
- <dependency>
- <groupId>org.codehaus.plexus.webdav</groupId>
- <artifactId>plexus-webdav-simple</artifactId>
- <version>1.0-alpha-1</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-xwork-integration</artifactId>
- <version>1.0-alpha-6-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-utils</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.derby</groupId>
- <artifactId>derby</artifactId>
- <version>10.1.3.1</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.mail</groupId>
- <artifactId>mail</artifactId>
- <version>1.4</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.activation</groupId>
- <artifactId>activation</artifactId>
- <version>1.1</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-clean-plugin</artifactId>
- <version>2.1.1</version>
- <!-- This configuration is added to cleanup from war:inplace -->
- <configuration>
- <filesets>
- <fileset>
- <directory>${basedir}/src/main/webapp</directory>
- <includes>
- <!-- TODO: META-INF shouldn't be required, seems to be an issue with the current war plugin -->
- <include>META-INF</include>
- <include>images/pss</include>
- <!-- Images from other wars -->
- <include>template/pss</include>
- <!-- Templates from other wars -->
- <include>WEB-INF/classes</include>
- <!-- Classes and Resources from other wars -->
- <include>WEB-INF/lib</include>
- <!-- Dependencies from other wars -->
- <include>WEB-INF/database</include>
- <!-- Database location configured in application.xml -->
- <include>WEB-INF/logs</include>
- <!-- Log file location specified in application.xml -->
- <include>pss</include>
- <!-- plexus-security css and javascript -->
- <include>css/pss</include>
- <include>WEB-INF/jsp/pss</include>
- <!-- plexus-security jsps -->
- <include>WEB-INF/template/pss</include>
- <!-- plexus-security xwork templates -->
- <include>WEB-INF/logs</include>
- <!-- Directory created by jetty:run -->
- <include>WEB-INF/temp</include>
- <!-- Directory created by jetty:run -->
- </includes>
- </fileset>
- </filesets>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-war-plugin</artifactId>
- <version>2.0.1</version>
- <configuration>
- <!-- Some versions of maven-war-plugin (snapshots) have this incorrectly defaulted to true.
- Specifically setting this to false to avoid accidental jar file creation. -->
- <archiveClasses>false</archiveClasses>
- <dependentWarExcludes>META-INF/**,WEB-INF/web.xml,WEB-INF/classes/xwork.xml</dependentWarExcludes>
- </configuration>
- <!-- TODO: would be good to make the jetty plugin aware of these and remove the below -->
- <executions>
- <execution>
- <phase>compile</phase>
- <goals>
- <!-- Needed to get the plexus-security war overlay to do its thing before jetty:run -->
- <goal>inplace</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>maven-jetty-plugin</artifactId>
- <version>6.1.1</version>
- <configuration>
- <scanIntervalSeconds>10</scanIntervalSeconds>
- <contextPath>/</contextPath>
- <jettyEnvXml>src/jetty-env.xml</jettyEnvXml>
- <connectors>
- <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
- <port>9091</port>
- <maxIdleTime>60000</maxIdleTime>
- </connector>
- </connectors>
- <systemProperties>
- <systemProperty>
- <name>appserver.base</name>
- <value>${project.build.directory}/appserver-base</value>
- </systemProperty>
- <systemProperty>
- <name>derby.system.home</name>
- <value>${project.build.directory}/appserver-base/logs</value>
- </systemProperty>
- </systemProperties>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.apache.derby</groupId>
- <artifactId>derby</artifactId>
- <version>10.1.3.1</version>
- </dependency>
- </dependencies>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>dependency-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>copy</id>
- <phase>process-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>${project.groupId}</groupId>
- <artifactId>archiva-applet</artifactId>
- <version>${project.version}</version>
- <outputDirectory>src/main/webapp</outputDirectory>
- <destFileName>archiva-applet.jar</destFileName>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-maven-plugin</artifactId>
- <configuration>
- <roleDefaults>
- <roleDefault>
- <role>com.opensymphony.xwork.Action</role>
- <instantiation-strategy>per-lookup</instantiation-strategy>
- </roleDefault>
- </roleDefaults>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <!-- TODO! add unit tests -->
- <configuration>
- <instrumentation>
- <excludes>
- <exclude>**/**</exclude>
- </excludes>
- </instrumentation>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-resources</phase>
- <goals>
- <goal>run</goal>
- </goals>
- <configuration>
- <tasks>
- <copy todir="${project.build.directory}/appserver-base">
- <fileset dir="src/appserver-base" />
- </copy>
- </tasks>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-<configuration />
+++ /dev/null
-<configuration />
+++ /dev/null
-<?xml version="1.0"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
-<Configure class="org.mortbay.jetty.webapp.WebAppContext">
-
- <New id="validation_mail" class="org.mortbay.jetty.plus.naming.Resource">
- <Arg>mail/Session</Arg>
- <Arg>
- <New class="org.mortbay.naming.factories.MailSessionReference">
- <Set name="user"></Set>
- <Set name="password"></Set>
- <Set name="properties">
- <New class="java.util.Properties">
- <Put name="mail.smtp.host">localhost</Put>
- <Put name="mail.smtp.port">25</Put> <!-- TODO: shouldn't this default? -->
- </New>
- </Set>
- </New>
- </Arg>
- </New>
-
- <!-- Archiva database -->
- <New id="archiva" class="org.mortbay.jetty.plus.naming.Resource">
- <Arg>jdbc/archiva</Arg>
- <Arg>
- <New class="org.apache.derby.jdbc.EmbeddedDataSource">
- <Set name="DatabaseName">target/databases/archiva</Set>
- <Set name="user">sa</Set>
- <Set name="createDatabase">create</Set>
- </New>
- </Arg>
- </New>
-
- <New id="archivaShutdown" class="org.mortbay.jetty.plus.naming.Resource">
- <Arg>jdbc/archivaShutdown</Arg>
- <Arg>
- <New class="org.apache.derby.jdbc.EmbeddedDataSource">
- <Set name="DatabaseName">target/databases/archiva</Set>
- <Set name="user">sa</Set>
- <Set name="shutdownDatabase">shutdown</Set>
- </New>
- </Arg>
- </New>
-
- <!-- Users / Security Database -->
- <New id="users" class="org.mortbay.jetty.plus.naming.Resource">
- <Arg>jdbc/users</Arg>
- <Arg>
- <New class="org.apache.derby.jdbc.EmbeddedDataSource">
- <Set name="DatabaseName">target/databases/users</Set>
- <Set name="user">sa</Set>
- <Set name="createDatabase">create</Set>
- </New>
- </Arg>
- </New>
-
- <New id="usersShutdown" class="org.mortbay.jetty.plus.naming.Resource">
- <Arg>jdbc/usersShutdown</Arg>
- <Arg>
- <New class="org.apache.derby.jdbc.EmbeddedDataSource">
- <Set name="DatabaseName">target/databases/users</Set>
- <Set name="user">sa</Set>
- <Set name="shutdownDatabase">shutdown</Set>
- </New>
- </Arg>
- </New>
-
-</Configure>
-
+++ /dev/null
-package org.apache.maven.archiva.web.action;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-public abstract class AbstractConfiguredAction
- extends PlexusActionSupport
-{
- /**
- * @plexus.requirement
- */
- private ConfiguredRepositoryFactory repositoryFactory;
-
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- protected ArtifactRepository createLocalRepository()
- {
- Configuration configuration = archivaConfiguration.getConfiguration();
-
- return repositoryFactory.createLocalRepository( configuration );
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
-import org.apache.maven.archiva.indexer.RepositoryIndexException;
-import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-/**
- * Browse the repository.
- *
- * @todo cache should be a proper cache class that is a singleton requirement rather than static variables
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="browseAction"
- */
-public class BrowseAction
- extends PlexusActionSupport
-{
- /**
- * @plexus.requirement
- */
- private RepositoryArtifactIndexFactory factory;
-
- /**
- * @plexus.requirement
- */
- private ConfiguredRepositoryFactory repositoryFactory;
-
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- private List groups;
-
- private String groupId;
-
- private static final String GROUP_SEPARATOR = ".";
-
- private List artifactIds;
-
- private String artifactId;
-
- private List versions;
-
- private static GroupTreeNode rootNode;
-
- private static long groupCacheTime;
-
- public String browse()
- throws RepositoryIndexException, IOException
- {
- RepositoryArtifactIndex index = getIndex();
-
- if ( !index.exists() )
- {
- addActionError( "The repository is not yet indexed. Please wait, and then try again." );
- return ERROR;
- }
-
- GroupTreeNode rootNode = buildGroupTree( index );
-
- this.groups = collateGroups( rootNode );
-
- return SUCCESS;
- }
-
- public String browseGroup()
- throws RepositoryIndexException, IOException, RepositoryIndexSearchException
- {
- RepositoryArtifactIndex index = getIndex();
-
- if ( !index.exists() )
- {
- addActionError( "The repository is not yet indexed. Please wait, and then try again." );
- return ERROR;
- }
-
- GroupTreeNode rootNode = buildGroupTree( index );
-
- if ( StringUtils.isEmpty( groupId ) )
- {
- // TODO: i18n
- addActionError( "You must specify a group ID to browse" );
- return ERROR;
- }
-
- StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
- while ( tok.hasMoreTokens() )
- {
- String part = tok.nextToken();
-
- if ( !rootNode.getChildren().containsKey( part ) )
- {
- // TODO: i18n
- getLogger().debug(
- "Can't find part: " + part + " for groupId " + groupId + " in children " + rootNode.getChildren() );
- addActionError( "The group specified was not found" );
- return ERROR;
- }
- else
- {
- rootNode = (GroupTreeNode) rootNode.getChildren().get( part );
- }
- }
-
- this.groups = collateGroups( rootNode );
-
- this.artifactIds = index.getArtifactIds( groupId );
- Collections.sort( this.artifactIds );
-
- return SUCCESS;
- }
-
- public String browseArtifact()
- throws RepositoryIndexException, IOException, RepositoryIndexSearchException
- {
- RepositoryArtifactIndex index = getIndex();
-
- if ( StringUtils.isEmpty( groupId ) )
- {
- // TODO: i18n
- addActionError( "You must specify a group ID to browse" );
- return ERROR;
- }
-
- if ( StringUtils.isEmpty( artifactId ) )
- {
- // TODO: i18n
- addActionError( "You must specify a artifact ID to browse" );
- return ERROR;
- }
-
- this.versions = index.getVersions( groupId, artifactId );
- Collections.sort( this.versions );
-
- if ( versions.isEmpty() )
- {
- // TODO: i18n
- addActionError( "Could not find any artifacts with the given group and artifact ID" );
- return ERROR;
- }
-
- return SUCCESS;
- }
-
- private GroupTreeNode buildGroupTree( RepositoryArtifactIndex index )
- throws IOException, RepositoryIndexException
- {
- // TODO: give action message if indexing is in progress
-
- long lastUpdate = index.getLastUpdatedTime();
-
- if ( rootNode == null || lastUpdate > groupCacheTime )
- {
- List groups = index.getAllGroupIds();
-
- getLogger().info( "Loaded " + groups.size() + " groups from index" );
-
- rootNode = new GroupTreeNode();
-
- // build a tree structure
- for ( Iterator i = groups.iterator(); i.hasNext(); )
- {
- String groupId = (String) i.next();
-
- StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
-
- GroupTreeNode node = rootNode;
-
- while ( tok.hasMoreTokens() )
- {
- String part = tok.nextToken();
-
- if ( !node.getChildren().containsKey( part ) )
- {
- GroupTreeNode newNode = new GroupTreeNode( part, node );
- node.addChild( newNode );
- node = newNode;
- }
- else
- {
- node = (GroupTreeNode) node.getChildren().get( part );
- }
- }
- }
- groupCacheTime = lastUpdate;
- }
- else
- {
- getLogger().debug( "Loaded groups from cache" );
- }
-
- return rootNode;
- }
-
- private List collateGroups( GroupTreeNode rootNode )
- {
- List groups = new ArrayList();
- for ( Iterator i = rootNode.getChildren().values().iterator(); i.hasNext(); )
- {
- GroupTreeNode node = (GroupTreeNode) i.next();
-
- while ( node.getChildren().size() == 1 )
- {
- node = (GroupTreeNode) node.getChildren().values().iterator().next();
- }
-
- groups.add( node.getFullName() );
- }
- return groups;
- }
-
- private RepositoryArtifactIndex getIndex()
- throws RepositoryIndexException
- {
- Configuration configuration = archivaConfiguration.getConfiguration();
- File indexPath = new File( configuration.getIndexPath() );
-
- return factory.createStandardIndex( indexPath );
- }
-
- public List getGroups()
- {
- return groups;
- }
-
- public List getArtifactIds()
- {
- return artifactIds;
- }
-
- public String getGroupId()
- {
- return groupId;
- }
-
- public void setGroupId( String groupId )
- {
- this.groupId = groupId;
- }
-
- public String getArtifactId()
- {
- return artifactId;
- }
-
- public void setArtifactId( String artifactId )
- {
- this.artifactId = artifactId;
- }
-
- public List getVersions()
- {
- return versions;
- }
-
- private static class GroupTreeNode
- {
- private final String name;
-
- private final String fullName;
-
- private final Map children = new TreeMap();
-
- GroupTreeNode()
- {
- name = null;
- fullName = null;
- }
-
- GroupTreeNode( String name, GroupTreeNode parent )
- {
- this.name = name;
- this.fullName = parent.fullName != null ? parent.fullName + GROUP_SEPARATOR + name : name;
- }
-
- public String getName()
- {
- return name;
- }
-
- public String getFullName()
- {
- return fullName;
- }
-
- public Map getChildren()
- {
- return children;
- }
-
- public void addChild( GroupTreeNode newNode )
- {
- children.put( newNode.name, newNode );
- }
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.reporting.database.ReportingDatabase;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.codehaus.plexus.security.rbac.Resource;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-import java.util.List;
-
-/**
- * Repository reporting.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="reportsAction"
- * @todo split report access and report generation
- */
-public class ReportsAction
- extends PlexusActionSupport
- implements SecureAction
-{
- /**
- * @plexus.requirement
- */
- private ReportingDatabase database;
-
- private List reports;
-
- public String execute()
- throws Exception
- {
- reports = database.getArtifactDatabase().getAllArtifactResults();
-
- return SUCCESS;
- }
-
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
- {
- SecureActionBundle bundle = new SecureActionBundle();
-
- bundle.setRequiresAuthentication( true );
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL );
-
- return bundle;
- }
-
- public List getReports()
- {
- return reports;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.lucene.index.Term;
-import org.apache.lucene.queryParser.MultiFieldQueryParser;
-import org.apache.lucene.queryParser.ParseException;
-import org.apache.lucene.search.TermQuery;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
-import org.apache.maven.archiva.indexer.RepositoryIndexException;
-import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
-import org.apache.maven.archiva.indexer.lucene.LuceneQuery;
-import org.apache.maven.archiva.indexer.lucene.LuceneRepositoryArtifactIndex;
-import org.apache.maven.archiva.indexer.record.StandardIndexRecordFields;
-import org.apache.maven.archiva.web.util.VersionMerger;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.util.Collection;
-
-/**
- * Search all indexed fields by the given criteria.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="searchAction"
- */
-public class SearchAction
- extends PlexusActionSupport
-{
- /**
- * Query string.
- */
- private String q;
-
- /**
- * The MD5 to search by.
- */
- private String md5;
-
- /**
- * Search results.
- */
- private Collection searchResults;
-
- /**
- * @plexus.requirement
- */
- private RepositoryArtifactIndexFactory factory;
-
- /**
- * @plexus.requirement
- */
- private ConfiguredRepositoryFactory repositoryFactory;
-
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- private static final String RESULTS = "results";
-
- private static final String ARTIFACT = "artifact";
-
- private String infoMessage;
-
- public String quickSearch()
- throws MalformedURLException, RepositoryIndexException, RepositoryIndexSearchException, ParseException
- {
- // TODO: give action message if indexing is in progress
-
- assert q != null && q.length() != 0;
-
- RepositoryArtifactIndex index = getIndex();
-
- if ( !index.exists() )
- {
- addActionError( "The repository is not yet indexed. Please wait, and then try again." );
- return ERROR;
- }
-
- MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{StandardIndexRecordFields.GROUPID,
- StandardIndexRecordFields.ARTIFACTID, StandardIndexRecordFields.BASE_VERSION,
- StandardIndexRecordFields.CLASSIFIER, StandardIndexRecordFields.CLASSES, StandardIndexRecordFields.FILES,
- StandardIndexRecordFields.TYPE, StandardIndexRecordFields.PROJECT_NAME,
- StandardIndexRecordFields.PROJECT_DESCRIPTION}, LuceneRepositoryArtifactIndex.getAnalyzer() );
- searchResults = index.search( new LuceneQuery( parser.parse( q ) ) );
-
- if ( searchResults.isEmpty() )
- {
- addActionError( "No results found" );
- return INPUT;
- }
-
- searchResults = VersionMerger.merge( searchResults );
-
- return SUCCESS;
- }
-
- public String findArtifact()
- throws Exception
- {
- // TODO: give action message if indexing is in progress
-
- assert md5 != null && md5.length() != 0;
-
- RepositoryArtifactIndex index = getIndex();
-
- if ( !index.exists() )
- {
- addActionError( "The repository is not yet indexed. Please wait, and then try again." );
- return ERROR;
- }
-
- searchResults = index.search(
- new LuceneQuery( new TermQuery( new Term( StandardIndexRecordFields.MD5, md5.toLowerCase() ) ) ) );
-
- if ( searchResults.isEmpty() )
- {
- addActionError( "No results found" );
- return INPUT;
- }
- if ( searchResults.size() == 1 )
- {
- return ARTIFACT;
- }
- else
- {
- return RESULTS;
- }
- }
-
- private RepositoryArtifactIndex getIndex()
- throws RepositoryIndexException
- {
- Configuration configuration = archivaConfiguration.getConfiguration();
- File indexPath = new File( configuration.getIndexPath() );
-
- return factory.createStandardIndex( indexPath );
- }
-
- public String doInput()
- {
- return INPUT;
- }
-
- public String getQ()
- {
- return q;
- }
-
- public void setQ( String q )
- {
- this.q = q;
- }
-
- public String getMd5()
- {
- return md5;
- }
-
- public void setMd5( String md5 )
- {
- this.md5 = md5;
- }
-
- public Collection getSearchResults()
- {
- return searchResults;
- }
-
- public String getInfoMessage()
- {
- return infoMessage;
- }
-
- public void setInfoMessage( String infoMessage )
- {
- this.infoMessage = infoMessage;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.TermQuery;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
-import org.apache.maven.archiva.indexer.RepositoryIndexException;
-import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
-import org.apache.maven.archiva.indexer.lucene.LuceneQuery;
-import org.apache.maven.archiva.indexer.record.StandardArtifactIndexRecord;
-import org.apache.maven.archiva.proxy.ProxyException;
-import org.apache.maven.archiva.reporting.database.ArtifactResultsDatabase;
-import org.apache.maven.archiva.web.util.VersionMerger;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.factory.ArtifactFactory;
-import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.ArtifactCollector;
-import org.apache.maven.artifact.resolver.ArtifactResolutionException;
-import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.Model;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.MavenProjectBuilder;
-import org.apache.maven.project.ProjectBuildingException;
-import org.apache.maven.project.artifact.InvalidDependencyVersionException;
-import org.apache.maven.shared.dependency.tree.DependencyNode;
-import org.apache.maven.shared.dependency.tree.DependencyTree;
-import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
-import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Browse the repository.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="showArtifactAction"
- */
-public class ShowArtifactAction
- extends PlexusActionSupport
-{
- /**
- * @plexus.requirement
- */
- private ArtifactFactory artifactFactory;
-
- /**
- * @plexus.requirement
- */
- private ConfiguredRepositoryFactory repositoryFactory;
-
- /**
- * @plexus.requirement
- */
- private MavenProjectBuilder projectBuilder;
-
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- /**
- * @plexus.requirement
- */
- private RepositoryArtifactIndexFactory factory;
-
- /**
- * @plexus.requirement
- */
- private ArtifactMetadataSource artifactMetadataSource;
-
- /**
- * @plexus.requirement
- */
- private ArtifactCollector collector;
-
- /**
- * @plexus.requirement
- */
- private DependencyTreeBuilder dependencyTreeBuilder;
-
- /**
- * @plexus.requirement
- */
- ArtifactResultsDatabase artifactsDatabase;
-
- private String groupId;
-
- private String artifactId;
-
- private String version;
-
- private Model model;
-
- private Collection dependencies;
-
- private List dependencyTree;
-
- private String repositoryId;
-
- private String repositoryUrlName;
-
- private String artifactPath;
-
- private List mailingLists;
-
- private List reports;
-
- public String artifact()
- throws IOException, XmlPullParserException, ProjectBuildingException, ResourceDoesNotExistException,
- ProxyException, ArtifactResolutionException
- {
- if ( !checkParameters() )
- {
- return ERROR;
- }
-
- MavenProject project = readProject();
-
- model = project.getModel();
-
- return SUCCESS;
- }
-
- public String dependencies()
- throws IOException, XmlPullParserException, ProjectBuildingException
- {
- if ( !checkParameters() )
- {
- return ERROR;
- }
-
- MavenProject project = readProject();
-
- model = project.getModel();
-
- // TODO: should this be the whole set of artifacts, and be more like the maven dependencies report?
- this.dependencies = VersionMerger.wrap( project.getModel().getDependencies() );
-
- return SUCCESS;
- }
-
- public String mailingLists()
- throws IOException, XmlPullParserException, ProjectBuildingException
- {
- if ( !checkParameters() )
- {
- return ERROR;
- }
-
- MavenProject project = readProject();
-
- model = project.getModel();
-
- this.mailingLists = project.getMailingLists();
-
- return SUCCESS;
- }
-
- public String reports()
- throws IOException, XmlPullParserException, ProjectBuildingException
- {
- if ( !checkParameters() )
- {
- return ERROR;
- }
-
- System.out.println("#### In reports.");
- this.reports = artifactsDatabase.findArtifactResults( groupId, artifactId, version );
- System.out.println("#### Found " + reports.size() + " reports.");
-
- return SUCCESS;
- }
-
- public String dependees()
- throws IOException, XmlPullParserException, ProjectBuildingException, RepositoryIndexException,
- RepositoryIndexSearchException
- {
- if ( !checkParameters() )
- {
- return ERROR;
- }
-
- MavenProject project = readProject();
-
- model = project.getModel();
-
- RepositoryArtifactIndex index = getIndex();
-
- String id = createId( groupId, artifactId, version );
- List records = index.search( new LuceneQuery( new TermQuery( new Term( "dependencies", id ) ) ) );
-
- dependencies = VersionMerger.merge( records );
-
- return SUCCESS;
- }
-
- public String dependencyTree()
- throws ProjectBuildingException, InvalidDependencyVersionException, ArtifactResolutionException
- {
- if ( !checkParameters() )
- {
- return ERROR;
- }
-
- Configuration configuration = archivaConfiguration.getConfiguration();
- List repositories = repositoryFactory.createRepositories( configuration );
-
- Artifact artifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
- // TODO: maybe we can decouple the assembly parts of the project builder from the repository handling to get rid of the temp repo
- ArtifactRepository localRepository = repositoryFactory.createLocalRepository( configuration );
- MavenProject project = projectBuilder.buildFromRepository( artifact, repositories, localRepository );
-
- model = project.getModel();
-
- getLogger().debug( " processing : " + groupId + ":" + artifactId + ":" + version );
-
- DependencyTree dependencies = collectDependencies( project, localRepository );
-
- this.dependencyTree = new ArrayList();
-
- populateFlatTreeList( dependencies.getRootNode(), dependencyTree );
-
- return SUCCESS;
- }
-
- private void populateFlatTreeList( DependencyNode currentNode, List dependencyList )
- {
- DependencyNode childNode;
-
- for ( Iterator iterator = currentNode.getChildren().iterator(); iterator.hasNext(); )
- {
- childNode = (DependencyNode) iterator.next();
- dependencyList.add( childNode );
- populateFlatTreeList( childNode, dependencyList );
- }
- }
-
- private DependencyTree collectDependencies( MavenProject project, ArtifactRepository localRepository )
- throws ArtifactResolutionException, ProjectBuildingException, InvalidDependencyVersionException
- {
- try
- {
- return dependencyTreeBuilder.buildDependencyTree( project, localRepository, artifactFactory,
- artifactMetadataSource, collector );
- }
- catch ( DependencyTreeBuilderException e )
- {
- getLogger().error( "Unable to build dependency tree.", e );
- return null;
- }
- }
-
- private static String createId( String groupId, String artifactId, String version )
- {
- return groupId + ":" + artifactId + ":" + version;
- }
-
- private RepositoryArtifactIndex getIndex()
- throws RepositoryIndexException
- {
- Configuration configuration = archivaConfiguration.getConfiguration();
- File indexPath = new File( configuration.getIndexPath() );
-
- return factory.createStandardIndex( indexPath );
- }
-
- private MavenProject readProject()
- throws ProjectBuildingException
- {
- Configuration configuration = archivaConfiguration.getConfiguration();
- List repositories = repositoryFactory.createRepositories( configuration );
-
- Artifact artifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
- // TODO: maybe we can decouple the assembly parts of the project builder from the repository handling to get rid of the temp repo
- ArtifactRepository localRepository = repositoryFactory.createLocalRepository( configuration );
- return projectBuilder.buildFromRepository( artifact, repositories, localRepository );
- }
-
- private boolean checkParameters()
- {
- boolean result = true;
-
- if ( StringUtils.isEmpty( groupId ) )
- {
- // TODO: i18n
- addActionError( "You must specify a group ID to browse" );
- result = false;
- }
-
- else if ( StringUtils.isEmpty( artifactId ) )
- {
- // TODO: i18n
- addActionError( "You must specify a artifact ID to browse" );
- result = false;
- }
-
- else if ( StringUtils.isEmpty( version ) )
- {
- // TODO: i18n
- addActionError( "You must specify a version to browse" );
- result = false;
- }
- return result;
- }
-
- public Model getModel()
- {
- return model;
- }
-
- public Collection getDependencies()
- {
- return dependencies;
- }
-
- public String getGroupId()
- {
- return groupId;
- }
-
- public void setGroupId( String groupId )
- {
- this.groupId = groupId;
- }
-
- public String getArtifactId()
- {
- return artifactId;
- }
-
- public void setArtifactId( String artifactId )
- {
- this.artifactId = artifactId;
- }
-
- public List getDependencyTree()
- {
- return dependencyTree;
- }
-
- public String getVersion()
- {
- return version;
- }
-
- public void setVersion( String version )
- {
- this.version = version;
- }
-
- public String getArtifactPath()
- {
- return artifactPath;
- }
-
- public static class DependencyWrapper
- {
- private final String groupId;
-
- private final String artifactId;
-
- /**
- * Versions added. We ignore duplicates since you might add those with varying classifiers.
- */
- private Set versions = new HashSet();
-
- private String version;
-
- private String scope;
-
- private String classifier;
-
- public DependencyWrapper( StandardArtifactIndexRecord record )
- {
- this.groupId = record.getGroupId();
-
- this.artifactId = record.getArtifactId();
-
- addVersion( record.getVersion() );
- }
-
- public DependencyWrapper( Dependency dependency )
- {
- this.groupId = dependency.getGroupId();
-
- this.artifactId = dependency.getArtifactId();
-
- this.scope = dependency.getScope();
-
- this.classifier = dependency.getClassifier();
-
- addVersion( dependency.getVersion() );
- }
-
- public String getScope()
- {
- return scope;
- }
-
- public String getClassifier()
- {
- return classifier;
- }
-
- public void addVersion( String version )
- {
- // We use DefaultArtifactVersion to get the correct sorting order later, however it does not have
- // hashCode properly implemented, so we add it here.
- // TODO: add these methods to the actual DefaultArtifactVersion and use that.
- versions.add( new DefaultArtifactVersion( version )
- {
- public int hashCode()
- {
- int result;
- result = getBuildNumber();
- result = 31 * result + getMajorVersion();
- result = 31 * result + getMinorVersion();
- result = 31 * result + getIncrementalVersion();
- result = 31 * result + ( getQualifier() != null ? getQualifier().hashCode() : 0 );
- return result;
- }
-
- public boolean equals( Object o )
- {
- if ( this == o )
- {
- return true;
- }
- if ( o == null || getClass() != o.getClass() )
- {
- return false;
- }
-
- DefaultArtifactVersion that = (DefaultArtifactVersion) o;
-
- if ( getBuildNumber() != that.getBuildNumber() )
- {
- return false;
- }
- if ( getIncrementalVersion() != that.getIncrementalVersion() )
- {
- return false;
- }
- if ( getMajorVersion() != that.getMajorVersion() )
- {
- return false;
- }
- if ( getMinorVersion() != that.getMinorVersion() )
- {
- return false;
- }
- if ( getQualifier() != null ? !getQualifier().equals( that.getQualifier() )
- : that.getQualifier() != null )
- {
- return false;
- }
-
- return true;
- }
- } );
-
- if ( versions.size() == 1 )
- {
- this.version = version;
- }
- else
- {
- this.version = null;
- }
- }
-
- public String getGroupId()
- {
- return groupId;
- }
-
- public String getArtifactId()
- {
- return artifactId;
- }
-
- public List getVersions()
- {
- List versions = new ArrayList( this.versions );
- Collections.sort( versions );
- return versions;
- }
-
- public String getVersion()
- {
- return version;
- }
- }
-
- public String getRepositoryId()
- {
- return repositoryId;
- }
-
- public List getMailingLists()
- {
- return mailingLists;
- }
-
- public String getRepositoryUrlName()
- {
- return repositoryUrlName;
- }
-
- public List getReports()
- {
- return reports;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.xwork.ModelDriven;
-import com.opensymphony.xwork.Preparable;
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.InvalidConfigurationException;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-import org.codehaus.plexus.rbac.profile.RoleProfileManager;
-import org.codehaus.plexus.registry.RegistryException;
-import org.codehaus.plexus.security.rbac.RbacManagerException;
-import org.codehaus.plexus.security.rbac.Resource;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-import java.io.IOException;
-
-/**
- * Base action for repository configuration actions.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- */
-public abstract class AbstractConfigureRepositoryAction
- extends PlexusActionSupport
- implements ModelDriven, Preparable, SecureAction
-{
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- /**
- * @plexus.requirement role-hint="archiva"
- */
- protected RoleProfileManager roleProfileManager;
-
- /**
- * The repository.
- */
- private AbstractRepositoryConfiguration repository;
-
- /**
- * The repository ID to lookup when editing a repository.
- */
- private String repoId;
-
- /**
- * The previously read configuration.
- */
- protected Configuration configuration;
-
- public String add()
- throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException, RegistryException
- {
- // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
-
- AbstractRepositoryConfiguration existingRepository = getRepository( repository.getId() );
- if ( existingRepository != null )
- {
- addFieldError( "id", "A repository with that id already exists" );
- return INPUT;
- }
-
- return saveConfiguration();
- }
-
- public String edit()
- throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException, RegistryException
- {
- // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
-
- AbstractRepositoryConfiguration existingRepository = getRepository( repository.getId() );
- removeRepository( existingRepository );
-
- return saveConfiguration();
- }
-
- protected abstract void removeRepository( AbstractRepositoryConfiguration existingRepository );
-
- protected abstract AbstractRepositoryConfiguration getRepository( String id );
-
- private String saveConfiguration()
- throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException, RegistryException
- {
- addRepository();
-
- archivaConfiguration.save( configuration );
-
- // TODO: do we need to check if indexing is needed?
-
- addActionMessage( "Successfully saved configuration" );
-
- return SUCCESS;
- }
-
- protected abstract void addRepository()
- throws IOException, RoleProfileException;
-
- public String input()
- {
- return INPUT;
- }
-
- public Object getModel()
- {
- return repository;
- }
-
- protected abstract AbstractRepositoryConfiguration createRepository();
-
- public void prepare()
- {
- configuration = archivaConfiguration.getConfiguration();
-
- if ( repository == null )
- {
- repository = getRepository( repoId );
- }
- if ( repository == null )
- {
- repository = createRepository();
- }
- }
-
- public String getRepoId()
- {
- return repoId;
- }
-
- public void setRepoId( String repoId )
- {
- this.repoId = repoId;
- }
-
- protected AbstractRepositoryConfiguration getRepository()
- {
- return repository;
- }
-
- public Configuration getConfiguration()
- {
- return configuration;
- }
-
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
- {
- SecureActionBundle bundle = new SecureActionBundle();
-
- bundle.setRequiresAuthentication( true );
-
- if ( getRepoId() != null )
- {
- // TODO: this is not right. It needs to change based on method. But is this really the right way to restrict this area?
- // TODO: not right. We only care about this permission on managed repositories. Otherwise, it's configuration
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY, getRepoId() );
- }
- else
- {
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
- }
-
- return bundle;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.InvalidConfigurationException;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.codehaus.plexus.rbac.profile.RoleProfileManager;
-import org.codehaus.plexus.registry.RegistryException;
-import org.codehaus.plexus.security.rbac.Resource;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-import java.io.IOException;
-
-/**
- * Base action for repository removal actions.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- */
-public abstract class AbstractDeleteRepositoryAction
- extends PlexusActionSupport
- implements SecureAction
-{
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- /**
- * The repository ID to lookup when editing a repository.
- */
- protected String repoId;
-
- /**
- * Which operation to select.
- */
- private String operation = "unmodified";
-
- /**
- * @plexus.requirement role-hint="archiva"
- */
- protected RoleProfileManager roleProfileManager;
-
- public String execute()
- throws IOException, InvalidConfigurationException, RegistryException
- {
- // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
-
- if ( "delete-entry".equals( operation ) || "delete-contents".equals( operation ) )
- {
- Configuration configuration = archivaConfiguration.getConfiguration();
-
- AbstractRepositoryConfiguration existingRepository = getRepository( configuration );
- if ( existingRepository == null )
- {
- addActionError( "A repository with that id does not exist" );
- return ERROR;
- }
-
- // TODO: remove from index too!
-
- removeRepository( configuration, existingRepository );
-
- archivaConfiguration.save( configuration );
-
- if ( "delete-contents".equals( operation ) )
- {
- removeContents( existingRepository );
- }
- }
-
- return SUCCESS;
- }
-
- protected abstract void removeContents( AbstractRepositoryConfiguration existingRepository )
- throws IOException;
-
- protected abstract AbstractRepositoryConfiguration getRepository( Configuration configuration );
-
- protected abstract void removeRepository( Configuration configuration,
- AbstractRepositoryConfiguration existingRepository );
-
- public String input()
- {
- return INPUT;
- }
-
- public String getRepoId()
- {
- return repoId;
- }
-
- public void setRepoId( String repoId )
- {
- this.repoId = repoId;
- }
-
- public String getOperation()
- {
- return operation;
- }
-
- public void setOperation( String operation )
- {
- this.operation = operation;
- }
-
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
- {
- SecureActionBundle bundle = new SecureActionBundle();
-
- bundle.setRequiresAuthentication( true );
-
- if ( getRepoId() != null )
- {
- // TODO: not right. We only care about this permission on managed repositories. Otherwise, it's configuration
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY, getRepoId() );
- }
- else
- {
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
- }
-
- return bundle;
- }
-
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.xwork.ModelDriven;
-import com.opensymphony.xwork.Preparable;
-import com.opensymphony.xwork.Validateable;
-
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.InvalidConfigurationException;
-import org.apache.maven.archiva.indexer.RepositoryIndexException;
-import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
-import org.apache.maven.archiva.repositories.ActiveManagedRepositories;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.codehaus.plexus.registry.RegistryException;
-import org.codehaus.plexus.scheduler.CronExpressionValidator;
-import org.codehaus.plexus.security.rbac.Resource;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Date;
-
-/**
- * Configures the application.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureAction"
- */
-public class ConfigureAction
- extends PlexusActionSupport
- implements ModelDriven, Preparable, Validateable, SecureAction
-{
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- /**
- * @plexus.requirement
- */
- private ActiveManagedRepositories activeRepositories;
-
- /**
- * The configuration.
- */
- private Configuration configuration;
-
- private CronExpressionValidator cronValidator;
-
- private String second = "0";
-
- private String minute = "0";
-
- private String hour = "*";
-
- private String dayOfMonth = "*";
-
- private String month = "*";
-
- private String dayOfWeek = "?";
-
- private String year;
-
- private String lastIndexingTime;
-
- public void validate()
- {
- //validate cron expression
- cronValidator = new CronExpressionValidator();
-
- if ( !cronValidator.validate( getCronExpression() ) )
- {
- addActionError( "Invalid Cron Expression" );
- }
- }
-
- public String execute()
- throws IOException, RepositoryIndexException, RepositoryIndexSearchException, InvalidConfigurationException,
- RegistryException
- {
- // TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
- // TODO: if this is changed, do we move the index or recreate it?
- configuration.setDataRefreshCronExpression( getCronExpression() );
-
- // Normalize the path
- File file = new File( configuration.getIndexPath() );
- configuration.setIndexPath( file.getCanonicalPath() );
- if ( !file.exists() )
- {
- file.mkdirs();
- // TODO: error handling when this fails, or is not a directory!
- }
-
- // Just double checking that our validation routines line up with what is expected in the configuration
- assert configuration.isValid();
-
- archivaConfiguration.save( configuration );
-
- // TODO: if the repository has changed, we need to check if indexing is needed!
-
- addActionMessage( "Successfully saved configuration" );
-
- return SUCCESS;
- }
-
- public String input()
- {
- String[] cronEx = configuration.getDataRefreshCronExpression().split( " " );
- int i = 0;
-
- while ( i < cronEx.length )
- {
- switch ( i )
- {
- case 0:
- second = cronEx[i];
- break;
- case 1:
- minute = cronEx[i];
- break;
- case 2:
- hour = cronEx[i];
- break;
- case 3:
- dayOfMonth = cronEx[i];
- break;
- case 4:
- month = cronEx[i];
- break;
- case 5:
- dayOfWeek = cronEx[i];
- break;
- case 6:
- year = cronEx[i];
- break;
- }
- i++;
- }
-
- if ( activeRepositories.getLastDataRefreshTime() != 0 )
- {
- lastIndexingTime = new Date( activeRepositories.getLastDataRefreshTime() ).toString();
- }
- else
- {
- lastIndexingTime = "Never been run.";
- }
-
- return INPUT;
- }
-
- public Object getModel()
- {
- return configuration;
- }
-
- public void prepare()
- {
- configuration = archivaConfiguration.getConfiguration();
- }
-
- public String getLastIndexingTime()
- {
- return lastIndexingTime;
- }
-
- public void setLastIndexingTime( String lastIndexingTime )
- {
- this.lastIndexingTime = lastIndexingTime;
- }
-
- public String getSecond()
- {
- return second;
- }
-
- public void setSecond( String second )
- {
- this.second = second;
- }
-
- public String getMinute()
- {
- return minute;
- }
-
- public void setMinute( String minute )
- {
- this.minute = minute;
- }
-
- public String getHour()
- {
- return hour;
- }
-
- public void setHour( String hour )
- {
- this.hour = hour;
- }
-
- public String getDayOfMonth()
- {
- return dayOfMonth;
- }
-
- public void setDayOfMonth( String dayOfMonth )
- {
- this.dayOfMonth = dayOfMonth;
- }
-
- public String getYear()
- {
- return year;
- }
-
- public void setYear( String year )
- {
- this.year = year;
- }
-
- public String getMonth()
- {
- return month;
- }
-
- public void setMonth( String month )
- {
- this.month = month;
- }
-
- public String getDayOfWeek()
- {
- return dayOfWeek;
- }
-
- public void setDayOfWeek( String dayOfWeek )
- {
- this.dayOfWeek = dayOfWeek;
- }
-
- private String getCronExpression()
- {
- return ( second + " " + minute + " " + hour + " " + dayOfMonth + " " + month + " " + dayOfWeek + " " +
- year ).trim();
- }
-
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
- {
- SecureActionBundle bundle = new SecureActionBundle();
-
- bundle.setRequiresAuthentication( true );
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
-
- return bundle;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.xwork.ModelDriven;
-import com.opensymphony.xwork.Preparable;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.apache.maven.archiva.web.action.AbstractConfiguredAction;
-import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
-import org.apache.maven.model.Model;
-import org.apache.maven.project.ProjectBuildingException;
-import org.apache.maven.shared.app.company.CompanyPomHandler;
-import org.apache.maven.shared.app.configuration.Configuration;
-import org.apache.maven.shared.app.configuration.MavenAppConfiguration;
-import org.codehaus.plexus.registry.RegistryException;
-import org.codehaus.plexus.security.rbac.Resource;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
-
-import java.io.IOException;
-
-/**
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @version $Id: ConfigurationAction.java 480950 2006-11-30 14:58:35Z evenisse $
- * @plexus.component role="com.opensymphony.xwork.Action"
- * role-hint="configureAppearance"
- */
-public class ConfigureAppearanceAction
- extends AbstractConfiguredAction
- implements ModelDriven, SecureAction, Preparable
-{
- /**
- * @plexus.requirement
- */
- private MavenAppConfiguration appConfigurationStore;
-
- /**
- * The configuration.
- */
- private Configuration configuration;
-
- private Model companyModel;
-
- /**
- * @plexus.requirement
- */
- private CompanyPomHandler companyPomHandler;
-
- public String execute()
- throws IOException, RegistryException
- {
- appConfigurationStore.save( configuration );
-
- return SUCCESS;
- }
-
- public Object getModel()
- {
- return configuration;
- }
-
- public void prepare()
- throws ProjectBuildingException, ArtifactMetadataRetrievalException
- {
- configuration = appConfigurationStore.getConfiguration();
-
- companyModel = companyPomHandler.getCompanyPomModel( configuration.getCompanyPom(), createLocalRepository() );
- }
-
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
- {
- SecureActionBundle bundle = new SecureActionBundle();
- bundle.setRequiresAuthentication( true );
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
-
- return bundle;
- }
-
- public Model getCompanyModel()
- {
- return companyModel;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration;
-
-import java.io.IOException;
-
-/**
- * Configures the application repositories.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureProxiedRepositoryAction"
- */
-public class ConfigureProxiedRepositoryAction
- extends AbstractConfigureRepositoryAction
-{
- protected void removeRepository( AbstractRepositoryConfiguration existingRepository )
- {
- configuration.removeProxiedRepository( (ProxiedRepositoryConfiguration) existingRepository );
- }
-
- protected AbstractRepositoryConfiguration getRepository( String id )
- {
- return configuration.getProxiedRepositoryById( id );
- }
-
- protected void addRepository()
- throws IOException
- {
- ProxiedRepositoryConfiguration repository = (ProxiedRepositoryConfiguration) getRepository();
-
- configuration.addProxiedRepository( repository );
- }
-
- protected AbstractRepositoryConfiguration createRepository()
- {
- return new ProxiedRepositoryConfiguration();
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.RepositoryConfiguration;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Configures the application repositories.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureRepositoryAction"
- */
-public class ConfigureRepositoryAction
- extends AbstractConfigureRepositoryAction
-{
- protected void removeRepository( AbstractRepositoryConfiguration existingRepository )
- {
- configuration.removeRepository( (RepositoryConfiguration) existingRepository );
- }
-
- protected AbstractRepositoryConfiguration getRepository( String id )
- {
- return configuration.getRepositoryById( id );
- }
-
- protected void addRepository()
- throws IOException, RoleProfileException
- {
- RepositoryConfiguration repository = (RepositoryConfiguration) getRepository();
-
- // Normalize the path
- File file = new File( repository.getDirectory() );
- repository.setDirectory( file.getCanonicalPath() );
- if ( !file.exists() )
- {
- file.mkdirs();
- // TODO: error handling when this fails, or is not a directory!
- }
-
- configuration.addRepository( repository );
-
- // TODO: double check these are configured on start up
- roleProfileManager.getDynamicRole( "archiva-repository-manager", repository.getId() );
-
- roleProfileManager.getDynamicRole( "archiva-repository-observer", repository.getId() );
- }
-
- protected AbstractRepositoryConfiguration createRepository()
- {
- RepositoryConfiguration repository = new RepositoryConfiguration();
- repository.setIndexed( false );
- return repository;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.SyncedRepositoryConfiguration;
-
-import java.io.IOException;
-
-/**
- * Configures the application repositories.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureSyncedRepositoryAction"
- */
-public class ConfigureSyncedRepositoryAction
- extends AbstractConfigureRepositoryAction
-{
- protected void removeRepository( AbstractRepositoryConfiguration existingRepository )
- {
- configuration.removeSyncedRepository( (SyncedRepositoryConfiguration) existingRepository );
- }
-
- protected AbstractRepositoryConfiguration getRepository( String id )
- {
- return configuration.getSyncedRepositoryById( id );
- }
-
- protected void addRepository()
- throws IOException
- {
- SyncedRepositoryConfiguration repository = (SyncedRepositoryConfiguration) getRepository();
-
- configuration.addSyncedRepository( repository );
- }
-
- protected AbstractRepositoryConfiguration createRepository()
- {
- return new SyncedRepositoryConfiguration();
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration;
-
-import java.io.IOException;
-
-/**
- * Configures the application repositories.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteProxiedRepositoryAction"
- */
-public class DeleteProxiedRepositoryAction
- extends AbstractDeleteRepositoryAction
-{
- protected AbstractRepositoryConfiguration getRepository( Configuration configuration )
- {
- return configuration.getProxiedRepositoryById( repoId );
- }
-
- protected void removeRepository( Configuration configuration, AbstractRepositoryConfiguration existingRepository )
- {
- configuration.removeProxiedRepository( (ProxiedRepositoryConfiguration) existingRepository );
- }
-
- protected void removeContents( AbstractRepositoryConfiguration existingRepository )
- throws IOException
- {
- // TODO! delete it
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.RepositoryConfiguration;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-import org.codehaus.plexus.util.FileUtils;
-
-import java.io.IOException;
-
-/**
- * Configures the application repositories.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteRepositoryAction"
- */
-public class DeleteRepositoryAction
- extends AbstractDeleteRepositoryAction
-{
- protected AbstractRepositoryConfiguration getRepository( Configuration configuration )
- {
- return configuration.getRepositoryById( repoId );
- }
-
- protected void removeRepository( Configuration configuration, AbstractRepositoryConfiguration existingRepository )
- {
- configuration.removeRepository( (RepositoryConfiguration) existingRepository );
-
- try
- {
- removeRepositoryRoles( existingRepository );
- }
- catch ( RoleProfileException e )
- {
- getLogger().error( "Error removing user roles associated with repository " + existingRepository.getId() );
- }
- }
-
- protected void removeContents( AbstractRepositoryConfiguration existingRepository )
- throws IOException
- {
- RepositoryConfiguration repository = (RepositoryConfiguration) existingRepository;
- getLogger().info( "Removing " + repository.getDirectory() );
- FileUtils.deleteDirectory( repository.getDirectory() );
- }
-
- /**
- * Remove user roles associated with the repository
- *
- * @param existingRepository
- * @throws RoleProfileException
- */
- private void removeRepositoryRoles( AbstractRepositoryConfiguration existingRepository )
- throws RoleProfileException
- {
- roleProfileManager.deleteDynamicRole( "archiva-repository-manager", existingRepository.getId() );
- roleProfileManager.deleteDynamicRole( "archiva-repository-observer", existingRepository.getId() );
-
- getLogger().info( "removed user roles associated with repository " + existingRepository.getId() );
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.SyncedRepositoryConfiguration;
-
-import java.io.IOException;
-
-/**
- * Configures the application repositories.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteSyncedRepositoryAction"
- */
-public class DeleteSyncedRepositoryAction
- extends AbstractDeleteRepositoryAction
-{
- protected AbstractRepositoryConfiguration getRepository( Configuration configuration )
- {
- return configuration.getSyncedRepositoryById( repoId );
- }
-
- protected void removeRepository( Configuration configuration, AbstractRepositoryConfiguration existingRepository )
- {
- configuration.removeSyncedRepository( (SyncedRepositoryConfiguration) existingRepository );
- }
-
- protected void removeContents( AbstractRepositoryConfiguration existingRepository )
- throws IOException
- {
- // TODO! remove the contents
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.xwork.ModelDriven;
-import com.opensymphony.xwork.Preparable;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.apache.maven.archiva.web.action.AbstractConfiguredAction;
-import org.apache.maven.artifact.installer.ArtifactInstallationException;
-import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
-import org.apache.maven.model.Model;
-import org.apache.maven.project.ProjectBuildingException;
-import org.apache.maven.shared.app.company.CompanyPomHandler;
-import org.apache.maven.shared.app.configuration.CompanyPom;
-import org.apache.maven.shared.app.configuration.Configuration;
-import org.apache.maven.shared.app.configuration.MavenAppConfiguration;
-import org.codehaus.plexus.security.rbac.Resource;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
-
-import java.io.IOException;
-
-/**
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @version $Id: ConfigurationAction.java 480950 2006-11-30 14:58:35Z evenisse $
- * @plexus.component role="com.opensymphony.xwork.Action"
- * role-hint="editPom"
- */
-public class EditPomAction
- extends AbstractConfiguredAction
- implements ModelDriven, SecureAction, Preparable
-{
- /**
- * @plexus.requirement
- */
- private MavenAppConfiguration appConfigurationStore;
-
- /**
- * The configuration.
- */
- private Configuration configuration;
-
- /**
- * @plexus.requirement
- */
- private CompanyPomHandler companyPomHandler;
-
- private Model companyModel;
-
- public String execute()
- throws IOException, ArtifactInstallationException
- {
- // TODO: hack for passed in String[]
- String[] logo = (String[]) companyModel.getProperties().get( "organization.logo" );
- if ( logo != null )
- {
- companyModel.getProperties().put( "organization.logo", logo[0] );
- }
-
- companyPomHandler.save( companyModel, createLocalRepository() );
-
- return SUCCESS;
- }
-
- public Object getModel()
- {
- return companyModel;
- }
-
- public void prepare()
- throws ProjectBuildingException, ArtifactMetadataRetrievalException
- {
- configuration = appConfigurationStore.getConfiguration();
-
- CompanyPom companyPom = configuration.getCompanyPom();
- companyModel = companyPomHandler.getCompanyPomModel( companyPom, createLocalRepository() );
-
- if ( companyModel == null )
- {
- companyModel = new Model();
- companyModel.setModelVersion( "4.0.0" );
- companyModel.setPackaging( "pom" );
-
- if ( companyPom != null )
- {
- companyModel.setGroupId( companyPom.getGroupId() );
- companyModel.setArtifactId( companyPom.getArtifactId() );
- }
- }
- }
-
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
- {
- SecureActionBundle bundle = new SecureActionBundle();
- bundle.setRequiresAuthentication( true );
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
-
- return bundle;
- }
-
- public Model getCompanyModel()
- {
- return companyModel;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.admin;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.scheduler.RepositoryTaskScheduler;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.codehaus.plexus.security.rbac.Resource;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
-import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
-import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
-import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-
-/**
- * Configures the application.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="runRepositoryTaskAction"
- */
-public class RunRepositoryTaskAction
- extends PlexusActionSupport
- implements SecureAction
-{
- /**
- * @plexus.requirement
- */
- private RepositoryTaskScheduler taskScheduler;
-
- public String runRefresh()
- throws TaskExecutionException
- {
- taskScheduler.runDataRefresh();
-
- return SUCCESS;
- }
-
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
- {
- SecureActionBundle bundle = new SecureActionBundle();
-
- bundle.setRequiresAuthentication( true );
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_RUN_INDEXER, Resource.GLOBAL );
-
- return bundle;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.action.component;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.web.action.AbstractConfiguredAction;
-import org.apache.maven.model.Model;
-import org.apache.maven.shared.app.company.CompanyPomHandler;
-import org.apache.maven.shared.app.configuration.MavenAppConfiguration;
-
-/**
- * Stores the company information for displaying on the page.
- *
- * @plexus.component role="com.opensymphony.xwork.Action" role-hint="companyInfo"
- */
-public class CompanyInfoAction
- extends AbstractConfiguredAction
-{
- private String companyLogo;
-
- private String companyUrl;
-
- private String companyName;
-
- /**
- * @plexus.requirement
- */
- private CompanyPomHandler handler;
-
- /**
- * @plexus.requirement
- */
- private MavenAppConfiguration appConfigurationStore;
-
- public String execute()
- throws Exception
- {
- Model model = handler.getCompanyPomModel( appConfigurationStore.getConfiguration().getCompanyPom(),
- createLocalRepository() );
-
- if ( model != null )
- {
- if ( model.getOrganization() != null )
- {
- companyName = model.getOrganization().getName();
- companyUrl = model.getOrganization().getUrl();
- }
-
- companyLogo = model.getProperties().getProperty( "organization.logo" );
- }
-
- return SUCCESS;
- }
-
- public String getCompanyLogo()
- {
- return companyLogo;
- }
-
- public String getCompanyUrl()
- {
- return companyUrl;
- }
-
- public String getCompanyName()
- {
- return companyName;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.apache.maven.archiva.web.check;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.RepositoryConfiguration;
-import org.codehaus.plexus.logging.AbstractLogEnabled;
-import org.codehaus.plexus.rbac.profile.RoleProfileException;
-import org.codehaus.plexus.rbac.profile.RoleProfileManager;
-import org.codehaus.plexus.security.system.check.EnvironmentCheck;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * RoleExistanceEnvironmentCheck:
- * <p/>
- * Under certain circumstances it is possible that the user store and/or role store
- * have been wiped or reset and its important to see if there are repositories already
- * configured in archiva that need to reinitialized in terms of having their roles created.
- *
- * @author: Jesse McConnell <jmcconnell@apache.org>
- * @version: $ID:
- * @plexus.component role="org.codehaus.plexus.security.system.check.EnvironmentCheck"
- * role-hint="repository-role-check"
- */
-public class RoleExistanceEnvironmentCheck
- extends AbstractLogEnabled
- implements EnvironmentCheck
-{
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- /**
- * @plexus.requirement role-hint="archiva"
- */
- private RoleProfileManager roleProfileManager;
-
- private boolean checked;
-
- public void validateEnvironment( List list )
- {
- if ( !checked )
- {
- try
- {
- // check if there is potential for role/repo disconnect
- Configuration configuration = archivaConfiguration.getConfiguration();
- if ( configuration.isValid() )
- {
- List repos = configuration.getRepositories();
-
- for ( Iterator i = repos.iterator(); i.hasNext(); )
- {
- RepositoryConfiguration repository = (RepositoryConfiguration) i.next();
-
- roleProfileManager.getDynamicRole( "archiva-repository-manager", repository.getId() );
-
- roleProfileManager.getDynamicRole( "archiva-repository-observer", repository.getId() );
- }
- }
- }
- catch ( RoleProfileException rpe )
- {
- list.add( this.getClass().getName() + "error initializing roles: " + rpe.getMessage() );
- getLogger().info( "error initializing roles", rpe );
- }
-
- checked = true;
- }
- }
-
-}
+++ /dev/null
-package org.apache.maven.archiva.web.interceptor;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.xwork.ActionInvocation;
-import com.opensymphony.xwork.interceptor.Interceptor;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.codehaus.plexus.logging.AbstractLogEnabled;
-
-/**
- * An interceptor that makes the application configuration available
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @plexus.component role="com.opensymphony.xwork.interceptor.Interceptor"
- * role-hint="configurationInterceptor"
- */
-public class ConfigurationInterceptor
- extends AbstractLogEnabled
- implements Interceptor
-{
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- /**
- * @param actionInvocation
- * @return
- * @throws Exception
- */
- public String intercept( ActionInvocation actionInvocation )
- throws Exception
- {
- Configuration configuration = archivaConfiguration.getConfiguration();
-
- if ( !configuration.isValid() )
- {
- if ( configuration.getRepositories().isEmpty() )
- {
- getLogger().info( "No repositories were configured - forwarding to repository configuration page" );
- return "config-repository-needed";
- }
- else
- {
- getLogger().info( "Configuration is incomplete - forwarding to configuration page" );
- return "config-needed";
- }
- }
- else
- {
- return actionInvocation.invoke();
- }
- }
-
- public void destroy()
- {
- // This space left intentionally blank
- }
-
- public void init()
- {
- // This space left intentionally blank
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.mapper;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
-import com.opensymphony.webwork.dispatcher.mapper.DefaultActionMapper;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Map alternate URLs to specific actions. Used for the repository browser and the proxy.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- */
-public class RepositoryActionMapper
- extends DefaultActionMapper
-{
- private static final String BROWSE_PREFIX = "/browse/";
-
- private static final String PROXY_PREFIX = "/proxy/";
-
- public String getUriFromActionMapping( ActionMapping actionMapping )
- {
- Map params = actionMapping.getParams();
- if ( "browseGroup".equals( actionMapping.getName() ) )
- {
- return BROWSE_PREFIX + params.remove( "groupId" );
- }
- else if ( "browseArtifact".equals( actionMapping.getName() ) )
- {
- return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" );
- }
- else if ( "showArtifact".equals( actionMapping.getName() ) )
- {
- return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
- params.remove( "version" );
- }
- else if ( "showArtifactDependencies".equals( actionMapping.getName() ) )
- {
- return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
- params.remove( "version" ) + "/dependencies";
- }
- else if ( "showArtifactMailingLists".equals( actionMapping.getName() ) )
- {
- return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
- params.remove( "version" ) + "/mailingLists";
- }
- else if ( "showArtifactDependees".equals( actionMapping.getName() ) )
- {
- return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
- params.remove( "version" ) + "/usedby";
- }
- else if ( "showArtifactDependencyTree".equals( actionMapping.getName() ) )
- {
- return BROWSE_PREFIX + params.remove( "groupId" ) + "/" + params.remove( "artifactId" ) + "/" +
- params.remove( "version" ) + "/dependencyTree";
- }
- else if ( "proxy".equals( actionMapping.getName() ) )
- {
- return PROXY_PREFIX + params.remove( "path" );
- }
-
- return super.getUriFromActionMapping( actionMapping );
- }
-
- public ActionMapping getMapping( HttpServletRequest httpServletRequest )
- {
- String path = httpServletRequest.getServletPath();
- if ( path.startsWith( BROWSE_PREFIX ) )
- {
- path = path.substring( BROWSE_PREFIX.length() );
- if ( path.length() == 0 )
- {
- return new ActionMapping( "browse", "/", "", null );
- }
- else
- {
- String[] parts = path.split( "/" );
- if ( parts.length == 1 )
- {
- Map params = new HashMap();
- params.put( "groupId", parts[0] );
- return new ActionMapping( "browseGroup", "/", "", params );
- }
- else if ( parts.length == 2 )
- {
- Map params = new HashMap();
- params.put( "groupId", parts[0] );
- params.put( "artifactId", parts[1] );
- return new ActionMapping( "browseArtifact", "/", "", params );
- }
- else if ( parts.length == 3 )
- {
- Map params = new HashMap();
- params.put( "groupId", parts[0] );
- params.put( "artifactId", parts[1] );
- params.put( "version", parts[2] );
- return new ActionMapping( "showArtifact", "/", "", params );
- }
- else if ( parts.length == 4 )
- {
- Map params = new HashMap();
- params.put( "groupId", parts[0] );
- params.put( "artifactId", parts[1] );
- params.put( "version", parts[2] );
-
- if ( "dependencies".equals( parts[3] ) )
- {
- return new ActionMapping( "showArtifactDependencies", "/", "", params );
- }
- else if ( "mailingLists".equals( parts[3] ) )
- {
- return new ActionMapping( "showArtifactMailingLists", "/", "", params );
- }
- else if ( "usedby".equals( parts[3] ) )
- {
- return new ActionMapping( "showArtifactDependees", "/", "", params );
- }
- else if ( "dependencyTree".equals( parts[3] ) )
- {
- return new ActionMapping( "showArtifactDependencyTree", "/", "", params );
- }
- }
- }
- }
- else if ( path.startsWith( PROXY_PREFIX ) )
- {
- // retain the leading /
- path = path.substring( PROXY_PREFIX.length() - 1 );
-
- Map params = new HashMap();
- params.put( "path", path );
- return new ActionMapping( "proxy", "/", "", params );
- }
-
- return super.getMapping( httpServletRequest );
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.repository;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.commons.lang.StringUtils;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
-import org.codehaus.plexus.webdav.DavServerComponent;
-import org.codehaus.plexus.webdav.DavServerListener;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * AuditLog - Audit Log.
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- *
- * @plexus.component role="org.apache.maven.archiva.web.repository.AuditLog"
- */
-public class AuditLog
- implements DavServerListener, Initializable
-{
- public static final String ROLE = AuditLog.class.getName();
-
- /**
- * @plexus.configuration default-value="${appserver.base}/logs/audit.log"
- */
- private File logFile;
-
- /**
- * @plexus.configuration default-value="yyyy-MM-dd HH:mm:ss"
- */
- private String timestampFormat;
-
- private PrintWriter writer;
-
- private SimpleDateFormat timestamp;
-
- private String getServerId( DavServerComponent server )
- {
- return "[" + server.getPrefix() + "]";
- }
-
- public void serverCollectionCreated( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Created Directory \"" + resource + "\"" );
- }
-
- public void serverCollectionRemoved( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Removed Directory \"" + resource + "\"" );
- }
-
- public void serverResourceCreated( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Created File \"" + resource + "\"" );
- }
-
- public void serverResourceModified( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Modified Existing File \"" + resource + "\"" );
- }
-
- public void serverResourceRemoved( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Removed File \"" + resource + "\"" );
- }
-
- /**
- * Log the message to the file.
- *
- * @param msg the message.
- */
- public void log( String msg )
- {
- // Synchronize to prevent threading issues.
- synchronized ( writer )
- {
- writer.println( timestamp.format( new Date() ) + " - " + msg );
- // Manually flush buffer to ensure data is written to disk.
- writer.flush();
- }
- }
-
- public void initialize()
- throws InitializationException
- {
- File parentDir = logFile.getParentFile();
- if ( parentDir != null )
- {
- if ( !parentDir.exists() )
- {
- parentDir.mkdirs();
- }
- }
-
- if ( StringUtils.isBlank( timestampFormat ) )
- {
- timestampFormat = "yyyy-MM-dd HH:mm:ss";
- }
-
- timestamp = new SimpleDateFormat( timestampFormat );
-
- try
- {
- writer = new PrintWriter( new FileWriter( logFile ) );
- log( "Logging Initialized." );
- }
- catch ( IOException e )
- {
- throw new InitializationException( "Unable to initialize log file writer: " + logFile.getAbsolutePath(), e );
- }
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.repository;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
-import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration;
-import org.apache.maven.archiva.configuration.Proxy;
-import org.apache.maven.archiva.configuration.RepositoryConfiguration;
-import org.apache.maven.archiva.proxy.ProxyException;
-import org.apache.maven.archiva.proxy.ProxyRequestHandler;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.wagon.ResourceDoesNotExistException;
-import org.apache.maven.wagon.proxy.ProxyInfo;
-import org.codehaus.plexus.webdav.AbstractDavServerComponent;
-import org.codehaus.plexus.webdav.DavServerComponent;
-import org.codehaus.plexus.webdav.DavServerException;
-import org.codehaus.plexus.webdav.servlet.DavServerRequest;
-import org.codehaus.plexus.webdav.util.WebdavMethodUtil;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * ProxiedDavServer
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- * @plexus.component role="org.codehaus.plexus.webdav.DavServerComponent"
- * role-hint="proxied"
- * instantiation-strategy="per-lookup"
- */
-public class ProxiedDavServer
- extends AbstractDavServerComponent
-{
- /**
- * @plexus.requirement role-hint="simple"
- */
- private DavServerComponent davServer;
-
- /**
- * @plexus.requirement
- */
- private ArchivaConfiguration archivaConfiguration;
-
- /**
- * @plexus.requirement role="org.apache.maven.archiva.proxy.ProxyRequestHandler"
- * @todo seems to be a bug in qdox that the role above is required
- */
- private ProxyRequestHandler proxyRequestHandler;
-
- /**
- * @plexus.requirement
- */
- private ConfiguredRepositoryFactory repositoryFactory;
-
- private RepositoryConfiguration repositoryConfiguration;
-
- private ArtifactRepository managedRepository;
-
- private List/*<ArtifactRepository>*/proxiedRepositories;
-
- private ProxyInfo wagonProxy;
-
- public String getPrefix()
- {
- return davServer.getPrefix();
- }
-
- public File getRootDirectory()
- {
- return davServer.getRootDirectory();
- }
-
- public void setPrefix( String prefix )
- {
- davServer.setPrefix( prefix );
- }
-
- public void setRootDirectory( File rootDirectory )
- {
- davServer.setRootDirectory( rootDirectory );
- }
-
- public void init( ServletConfig servletConfig )
- throws DavServerException
- {
- davServer.init( servletConfig );
-
- proxiedRepositories = new ArrayList();
-
- Configuration config = archivaConfiguration.getConfiguration();
-
- wagonProxy = createWagonProxy( config.getProxy() );
-
- repositoryConfiguration = config.getRepositoryByUrlName( getPrefix() );
-
- managedRepository = repositoryFactory.createRepository( repositoryConfiguration );
-
- for ( Iterator i = config.getProxiedRepositories().iterator(); i.hasNext(); )
- {
- ProxiedRepositoryConfiguration proxiedRepoConfig = (ProxiedRepositoryConfiguration) i.next();
-
- if ( proxiedRepoConfig.getManagedRepository().equals( repositoryConfiguration.getId() ) )
- {
- proxiedRepositories.add( repositoryFactory.createProxiedRepository( proxiedRepoConfig ) );
- }
- }
- }
-
- public void process( DavServerRequest request, HttpServletResponse response )
- throws DavServerException, ServletException, IOException
- {
- if ( WebdavMethodUtil.isReadMethod( request.getRequest().getMethod() ) )
- {
- if ( !hasResource( request.getLogicalResource() ) )
- {
- fetchContentFromProxies( request );
- }
- }
-
- davServer.process( request, response );
- }
-
- private void fetchContentFromProxies( DavServerRequest request )
- throws ServletException
- {
- try
- {
- proxyRequestHandler.get( request.getLogicalResource(), this.proxiedRepositories, this.managedRepository,
- this.wagonProxy );
- }
- catch ( ResourceDoesNotExistException e )
- {
- // TODO: getLogger().info( "Unable to fetch resource, it does not exist.", e );
- // return an HTTP 404 instead of HTTP 500 error.
- return;
- }
- catch ( ProxyException e )
- {
- throw new ServletException( "Unable to fetch resource.", e );
- }
- }
-
- private ProxyInfo createWagonProxy( Proxy proxy )
- {
- ProxyInfo proxyInfo = null;
- if ( proxy != null && StringUtils.isNotEmpty( proxy.getHost() ) )
- {
- proxyInfo = new ProxyInfo();
- proxyInfo.setHost( proxy.getHost() );
- proxyInfo.setPort( proxy.getPort() );
- proxyInfo.setUserName( proxy.getUsername() );
- proxyInfo.setPassword( proxy.getPassword() );
- proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
- proxyInfo.setType( proxy.getProtocol() );
- }
- return proxyInfo;
- }
-
- public RepositoryConfiguration getRepositoryConfiguration()
- {
- return repositoryConfiguration;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.repository;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.RepositoryConfiguration;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.codehaus.plexus.registry.Registry;
-import org.codehaus.plexus.registry.RegistryListener;
-import org.codehaus.plexus.security.authentication.AuthenticationException;
-import org.codehaus.plexus.security.authentication.AuthenticationResult;
-import org.codehaus.plexus.security.authorization.AuthorizationException;
-import org.codehaus.plexus.security.authorization.AuthorizationResult;
-import org.codehaus.plexus.security.policy.AccountLockedException;
-import org.codehaus.plexus.security.policy.MustChangePasswordException;
-import org.codehaus.plexus.security.system.SecuritySession;
-import org.codehaus.plexus.security.system.SecuritySystem;
-import org.codehaus.plexus.security.ui.web.filter.authentication.HttpAuthenticator;
-import org.codehaus.plexus.webdav.DavServerComponent;
-import org.codehaus.plexus.webdav.DavServerException;
-import org.codehaus.plexus.webdav.servlet.DavServerRequest;
-import org.codehaus.plexus.webdav.servlet.multiplexed.MultiplexedWebDavServlet;
-import org.codehaus.plexus.webdav.util.WebdavMethodUtil;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * RepositoryServlet
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class RepositoryServlet
- extends MultiplexedWebDavServlet
- implements RegistryListener
-{
- /**
- * @plexus.requirement
- */
- private SecuritySystem securitySystem;
-
- /**
- * @plexus.requirement role-hint="basic"
- */
- private HttpAuthenticator httpAuth;
-
- /**
- * @plexus.requirement
- */
- private AuditLog audit;
-
- private Configuration configuration;
-
- private ArchivaConfiguration archivaConfiguration;
-
- public void initComponents()
- throws ServletException
- {
- super.initComponents();
-
- securitySystem = (SecuritySystem) lookup( SecuritySystem.ROLE );
- httpAuth = (HttpAuthenticator) lookup( HttpAuthenticator.ROLE, "basic" );
- audit = (AuditLog) lookup( AuditLog.ROLE );
-
- archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class.getName() );
- configuration = archivaConfiguration.getConfiguration();
- archivaConfiguration.addChangeListener( this );
- }
-
- public void initServers( ServletConfig servletConfig )
- throws DavServerException
- {
- List repositories = configuration.getRepositories();
- Iterator itrepos = repositories.iterator();
- while ( itrepos.hasNext() )
- {
- RepositoryConfiguration repoConfig = (RepositoryConfiguration) itrepos.next();
- File repoDir = new File( repoConfig.getDirectory() );
-
- if ( !repoDir.exists() )
- {
- repoDir.mkdirs();
- }
-
- DavServerComponent server = createServer( repoConfig.getUrlName(), repoDir, servletConfig );
-
- server.addListener( audit );
- }
- }
-
- public RepositoryConfiguration getRepositoryConfiguration( DavServerRequest request )
- {
- return configuration.getRepositoryByUrlName( request.getPrefix() );
- }
-
- public String getRepositoryName( DavServerRequest request )
- {
- RepositoryConfiguration repoConfig = getRepositoryConfiguration( request );
- if ( repoConfig == null )
- {
- return "Unknown";
- }
-
- return repoConfig.getName();
- }
-
- public boolean isAuthenticated( DavServerRequest davRequest, HttpServletResponse response )
- throws ServletException, IOException
- {
- HttpServletRequest request = davRequest.getRequest();
-
- // Authentication Tests.
- try
- {
- AuthenticationResult result = httpAuth.getAuthenticationResult( request, response );
-
- if ( ( result != null ) && !result.isAuthenticated() )
- {
- // Must Authenticate.
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "User Credentials Invalid" ) );
- return false;
- }
-
- }
- catch ( AuthenticationException e )
- {
- log( "Fatal Http Authentication Error.", e );
- throw new ServletException( "Fatal Http Authentication Error.", e );
- }
- catch ( AccountLockedException e )
- {
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "User account is locked" ) );
- }
- catch ( MustChangePasswordException e )
- {
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "You must change your password." ) );
- }
-
- return true;
- }
-
- public boolean isAuthorized( DavServerRequest davRequest, HttpServletResponse response )
- throws ServletException, IOException
- {
- // Authorization Tests.
- HttpServletRequest request = davRequest.getRequest();
-
- boolean isWriteRequest = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-
- SecuritySession securitySession = httpAuth.getSecuritySession();
- try
- {
- String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
-
- if ( isWriteRequest )
- {
- permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
- }
-
- AuthorizationResult authzResult =
- securitySystem.authorize( securitySession, permission, getRepositoryConfiguration( davRequest )
- .getId() );
-
- if ( !authzResult.isAuthorized() )
- {
- if ( authzResult.getException() != null )
- {
- log( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest +
- ",permission=" + permission + "] : " + authzResult.getException().getMessage() );
- }
-
- // Issue HTTP Challenge.
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "Authorization Denied." ) );
- return false;
- }
- }
- catch ( AuthorizationException e )
- {
- throw new ServletException( "Fatal Authorization Subsystem Error." );
- }
-
- return true;
- }
-
- public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
- {
- // nothing to do
- }
-
- public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
- {
- configuration = archivaConfiguration.getConfiguration();
-
- if ( propertyName.startsWith( "repositories" ) )
- {
- log( "Triggering managed repository configuration change with " + propertyName + " set to " +
- propertyValue );
- getDavManager().removeAllServers();
-
- try
- {
- initServers( getServletConfig() );
- }
- catch ( DavServerException e )
- {
- log( "Error restarting WebDAV server after configuration change - service disabled: " + e.getMessage(),
- e );
- }
- }
- else
- {
- log( "Not triggering managed repository configuration change with " + propertyName );
- }
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.tags;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.webwork.WebWorkException;
-import com.opensymphony.webwork.components.Component;
-import com.opensymphony.xwork.util.OgnlValueStack;
-
-import org.apache.commons.lang.StringEscapeUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.common.artifact.managed.ManagedArtifact;
-import org.apache.maven.archiva.configuration.RepositoryConfiguration;
-import org.apache.maven.archiva.repositories.ActiveManagedRepositories;
-import org.apache.maven.project.ProjectBuildingException;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.jsp.PageContext;
-
-/**
- * DownloadArtifact
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- *
- * @plexus.component role="com.opensymphony.webwork.components.Component" role-hint="download-artifact"
- * instantiation-strategy="per-lookup"
- */
-public class DownloadArtifact
- extends Component
-{
- /**
- * @plexus.requirement
- */
- private ActiveManagedRepositories managedRepositories;
-
- private HttpServletRequest req;
-
- private HttpServletResponse res;
-
- private String groupId;
-
- private String artifactId;
-
- private String version;
-
- private boolean mini = false;
-
- public DownloadArtifact( OgnlValueStack stack, PageContext pageContext )
- {
- super( stack );
- this.req = (HttpServletRequest) pageContext.getRequest();
- this.res = (HttpServletResponse) pageContext.getResponse();
- try
- {
- managedRepositories = (ActiveManagedRepositories) PlexusTagUtil.lookup( pageContext,
- ActiveManagedRepositories.ROLE );
- }
- catch ( ComponentLookupException e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
- }
-
- public boolean end( Writer writer, String body )
- {
- StringBuffer sb = new StringBuffer();
-
- try
- {
- ManagedArtifact managedArtifact = managedRepositories.findArtifact( groupId, artifactId, version );
-
- if ( managedArtifact != null )
- {
- RepositoryConfiguration repoConfig = managedRepositories.getRepositoryConfiguration( managedArtifact
- .getRepositoryId() );
- String prefix = req.getContextPath() + "/repository/" + repoConfig.getUrlName();
-
- if ( mini )
- {
- appendMini( sb, prefix, managedArtifact );
- }
- else
- {
- appendNormal( sb, prefix, managedArtifact );
- }
- }
- }
- catch ( ProjectBuildingException e )
- {
- appendError( sb, e );
- }
-
- try
- {
- writer.write( sb.toString() );
- }
- catch ( IOException e )
- {
- throw new WebWorkException( "IOError: " + e.getMessage(), e );
- }
-
- return super.end( writer, body );
- }
-
- private void appendError( StringBuffer sb, ProjectBuildingException e )
- {
- /* do nothing */
- }
-
- private void appendMini( StringBuffer sb, String prefix, ManagedArtifact managedArtifact )
- {
- /* do nothing */
- }
-
- private void appendNormal( StringBuffer sb, String prefix, ManagedArtifact managedArtifact )
- {
- /*
- * <div class="download">
- * <div class="hd">
- * <div class="c"></div>
- * </div>
- * <div class="bd">
- * <div class="c">
- * <-- main content goes here -->
- * </div>
- * </div>
- * <div class="ft">
- * <div class="c"></div>
- * </div>
- * </div>
- */
-
- sb.append( "<div class=\"download\">" );
- sb.append( "<div class=\"hd\"><div class=\"c\"></div></div>" );
- sb.append( "<div class=\"bd\"><div class=\"c\">" );
-
- // Heading
- sb.append( "<h2>" );
- if ( managedArtifact.getAttached().isEmpty() )
- {
- sb.append( "Download" );
- }
- else
- {
- sb.append( "Downloads" );
- }
- sb.append( "</h2>" );
-
- // Body
- sb.append( "<p class=\"body\">" );
-
- appendLink( sb, prefix, managedArtifact.getPath(), "main" );
-
- Iterator it = managedArtifact.getAttached().entrySet().iterator();
- while ( it.hasNext() )
- {
- Map.Entry entry = (Entry) it.next();
- String type = (String) entry.getKey();
- String path = (String) entry.getValue();
-
- if ( StringUtils.isNotBlank( path ) )
- {
- sb.append( "<br/>" );
- appendLink( sb, prefix, path, type );
- }
- }
-
- sb.append( "</div>" ); // close "downloadbox.bd.c"
- sb.append( "</div>" ); // close "downloadbox.bd"
-
- sb.append( "<div class=\"ft\"><div class=\"c\"></div></div>" );
- sb.append( "</div>" ); // close "download"
- }
-
- private void appendLink( StringBuffer sb, String prefix, String path, String type )
- {
- StringBuffer url = new StringBuffer();
-
- url.append( prefix );
- url.append( "/" ).append( path );
-
- String filename = path.substring( path.lastIndexOf( "/" ) + 1 );
-
- sb.append( "<a href=\"" ).append( StringEscapeUtils.escapeXml( url.toString() ) ).append( "\"" );
- sb.append( " title=\"" ).append( "Download " ).append( StringEscapeUtils.escapeXml( filename ) ).append( "\"" );
- sb.append( ">" );
-
- sb.append( "<img src=\"" ).append( req.getContextPath() );
- sb.append( "/images/download-type-" ).append( type ).append( ".png\" />" );
-
- // TODO: Include file size / date in output ?
- sb.append( StringUtils.capitalize( type ) );
- sb.append( "</a>" );
- }
-
- public void setArtifactId( String artifactId )
- {
- this.artifactId = artifactId;
- }
-
- public void setGroupId( String groupId )
- {
- this.groupId = groupId;
- }
-
- public void setMini( boolean mini )
- {
- this.mini = mini;
- }
-
- public void setVersion( String version )
- {
- this.version = version;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.tags;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.webwork.views.jsp.TagUtils;
-
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.tagext.TagSupport;
-
-/**
- * DownloadArtifactTag
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class DownloadArtifactTag
- extends TagSupport
-{
- private String groupId_; // stores EL-based groupId property
-
- private String groupId; // stores the evaluated groupId object.
-
- private String artifactId_; // stores EL-based artifactId property
-
- private String artifactId; // stores the evaluated artifactId object.
-
- private String version_; // stores EL-based version property
-
- private String version; // stores the evaluated version object.
-
- private String mini_; // stores EL-based mini property
-
- private boolean mini; // stores the evaluated mini object.
-
- public int doEndTag()
- throws JspException
- {
- evaluateExpressions();
-
- DownloadArtifact download = new DownloadArtifact( TagUtils.getStack( pageContext ), pageContext );
- download.setGroupId( groupId );
- download.setArtifactId( artifactId );
- download.setVersion( version );
- download.setMini( mini );
-
- download.end( pageContext.getOut(), "" );
-
- return super.doEndTag();
- }
-
- private void evaluateExpressions()
- throws JspException
- {
- ExpressionTool exprTool = new ExpressionTool( pageContext, this, "download" );
-
- // Handle required properties.
- groupId = exprTool.requiredString( "groupId", groupId_ );
- artifactId = exprTool.requiredString( "artifactId", artifactId_ );
- version = exprTool.requiredString( "version", version_ );
-
- // Handle optional properties
- mini = exprTool.optionalBoolean( "mini", mini_, false );
- }
-
- public void setArtifactId( String artifactId )
- {
- this.artifactId_ = artifactId;
- }
-
- public void setGroupId( String groupId )
- {
- this.groupId_ = groupId;
- }
-
- public void setVersion( String version )
- {
- this.version_ = version;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.tags;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.taglibs.standard.tag.common.core.NullAttributeException;
-import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;
-
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.PageContext;
-import javax.servlet.jsp.tagext.Tag;
-
-/**
- * ExpressionTool
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class ExpressionTool
-{
- private PageContext pageContext;
-
- private Tag tag;
-
- private String tagName;
-
- public ExpressionTool( PageContext pageContext, Tag tag, String tagName )
- {
- this.pageContext = pageContext;
- this.tag = tag;
- this.tagName = tagName;
- }
-
- public boolean optionalBoolean( String propertyName, String expression, boolean defaultValue )
- throws JspException
- {
- try
- {
- Boolean ret = (Boolean) ExpressionUtil.evalNotNull( this.tagName, propertyName, expression, Boolean.class,
- this.tag, this.pageContext );
-
- if ( ret == null )
- {
- return defaultValue;
- }
-
- return ret.booleanValue();
- }
- catch ( NullAttributeException e )
- {
- return defaultValue;
- }
- }
-
- public String optionalString( String propertyName, String expression, String defaultValue )
- throws JspException
- {
- try
- {
- String ret = (String) ExpressionUtil.evalNotNull( this.tagName, propertyName, expression, String.class,
- this.tag, this.pageContext );
-
- if ( ret == null )
- {
- return defaultValue;
- }
-
- return ret;
- }
- catch ( NullAttributeException e )
- {
- return defaultValue;
- }
- }
-
- public String requiredString( String propertyName, String expression )
- throws JspException
- {
- try
- {
- String ret = (String) ExpressionUtil.evalNotNull( this.tagName, propertyName, expression, String.class,
- this.tag, this.pageContext );
- return ret;
- }
- catch ( NullAttributeException e )
- {
- String emsg = "Required " + this.tagName + " property [" + propertyName + "] is null!";
-
- log( emsg, e );
- throw new JspException( emsg );
- }
- }
-
- private void log( String msg, Throwable t )
- {
- pageContext.getServletContext().log( msg, t );
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.tags;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.webwork.WebWorkException;
-import com.opensymphony.webwork.components.Component;
-import com.opensymphony.xwork.util.OgnlValueStack;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.StringTokenizer;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * GroupIdLink
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class GroupIdLink
- extends Component
-{
- private static final String ACTION = "browseGroup";
-
- private static final String NAMESPACE = "/";
-
- private static final boolean includeContext = true;
-
- private static final boolean encode = true;
-
- private static final String method = null;
-
- private HttpServletRequest req;
-
- private HttpServletResponse res;
-
- private String groupId;
-
- private boolean includeTop = false;
-
- public GroupIdLink( OgnlValueStack stack, HttpServletRequest req, HttpServletResponse res )
- {
- super( stack );
- this.req = req;
- this.res = res;
- }
-
- public boolean end( Writer writer, String body )
- {
- StringBuffer sb = new StringBuffer();
-
- sb.append( "<span class=\"groupId\">" );
-
- if ( includeTop )
- {
- sb.append( "<a href=\"" );
- sb.append( determineBrowseActionUrl() );
- sb.append( "\">[top]</a> / " ); // TODO: i18n
- }
-
- StringTokenizer tok = new StringTokenizer( groupId, "." );
- String cumulativeGroup = null;
-
- while ( tok.hasMoreTokens() )
- {
- String token = tok.nextToken();
-
- if ( cumulativeGroup == null )
- {
- cumulativeGroup = token;
- }
- else
- {
- cumulativeGroup += "." + token;
- }
- sb.append( "<a href=\"" );
- sb.append( determineBrowseGroupActionUrl( cumulativeGroup ) );
- sb.append( "\">" ).append( token ).append( "</a> / " );
- }
-
- sb.append( "</span>" );
-
- try
- {
- writer.write( sb.toString() );
- }
- catch ( IOException e )
- {
- throw new WebWorkException( "IOError: " + e.getMessage(), e );
- }
-
- return super.end( writer, body );
- }
-
- private String determineBrowseActionUrl()
- {
- return determineActionURL( "browse", NAMESPACE, method, req, res, parameters, req.getScheme(), includeContext,
- encode );
- }
-
- private String determineBrowseGroupActionUrl( String gid )
- {
- parameters.put( "groupId", gid );
-
- return determineActionURL( ACTION, NAMESPACE, method, req, res, parameters, req.getScheme(), includeContext,
- encode );
- }
-
- public String getGroupId()
- {
- return groupId;
- }
-
- public void setGroupId( String groupId )
- {
- this.groupId = groupId;
- }
-
- public boolean isIncludeTop()
- {
- return includeTop;
- }
-
- public void setIncludeTop( boolean includeTop )
- {
- this.includeTop = includeTop;
- }
-
-}
+++ /dev/null
-package org.apache.maven.archiva.web.tags;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.webwork.views.jsp.TagUtils;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.tagext.TagSupport;
-
-/**
- * GroupIdLink
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class GroupIdLinkTag
- extends TagSupport
-{
- private String var_; // stores EL-based property
-
- private String var; // stores the evaluated object.
-
- private boolean includeTop = false;
-
- public void release()
- {
- var_ = null;
- var = null;
- includeTop = false;
-
- super.release();
- }
-
- public int doEndTag()
- throws JspException
- {
- evaluateExpressions();
-
- GroupIdLink gidlink = new GroupIdLink( TagUtils.getStack( pageContext ), (HttpServletRequest) pageContext
- .getRequest(), (HttpServletResponse) pageContext.getResponse() );
-
- gidlink.setGroupId( var );
- gidlink.setIncludeTop( includeTop );
-
- gidlink.end( pageContext.getOut(), "" );
-
- return super.doEndTag();
- }
-
- private void evaluateExpressions()
- throws JspException
- {
- ExpressionTool exprTool = new ExpressionTool( pageContext, this, "groupIdLink" );
-
- var = exprTool.optionalString( "var", var_, "" );
- }
-
- public void setVar( String value )
- {
- this.var_ = value;
- }
-
- public void setIncludeTop( boolean includeTop )
- {
- this.includeTop = includeTop;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.tags;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-
-import javax.servlet.ServletContext;
-import javax.servlet.jsp.PageContext;
-
-/**
- * PlexusTagUtil
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class PlexusTagUtil
-{
- public static Object lookup( PageContext pageContext, String role )
- throws ComponentLookupException
- {
- return getContainer( pageContext ).lookup( role );
- }
-
- public static Object lookup( PageContext pageContext, String role, String hint )
- throws ComponentLookupException
- {
- return getContainer( pageContext ).lookup( role, hint );
- }
-
- public static PlexusContainer getContainer( PageContext pageContext )
- throws ComponentLookupException
- {
- ServletContext servletContext = pageContext.getServletContext();
-
- PlexusContainer xworkContainer = (PlexusContainer) servletContext.getAttribute( "webwork.plexus.container" );
-
- if ( xworkContainer != null )
- {
- servletContext.setAttribute( PlexusConstants.PLEXUS_KEY, xworkContainer );
-
- return xworkContainer;
- }
-
- PlexusContainer container = (PlexusContainer) servletContext.getAttribute( PlexusConstants.PLEXUS_KEY );
- if ( container == null )
- {
- throw new ComponentLookupException( "PlexusContainer is null." );
- }
- return container;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.util;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import org.apache.maven.archiva.indexer.record.StandardArtifactIndexRecord;
-import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
-import org.apache.maven.model.Dependency;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class VersionMerger
-{
-
- public static List /*<DependencyWrapper>*/ wrap( List /*<StandardArtifactIndexRecord>*/ artifacts )
- {
- List dependencies = new ArrayList();
-
- for ( Iterator i = artifacts.iterator(); i.hasNext(); )
- {
- Dependency dependency = (Dependency) i.next();
-
- dependencies.add( new DependencyWrapper( dependency ) );
- }
-
- return dependencies;
- }
-
- public static Collection /*<DependencyWrapper*/ merge( Collection /*<StandardArtifactIndexRecord>*/ artifacts )
- {
- Map dependees = new LinkedHashMap();
-
- for ( Iterator i = artifacts.iterator(); i.hasNext(); )
- {
- StandardArtifactIndexRecord record = (StandardArtifactIndexRecord) i.next();
-
- String key = record.getGroupId() + ":" + record.getArtifactId();
- if ( dependees.containsKey( key ) )
- {
- DependencyWrapper wrapper = (DependencyWrapper) dependees.get( key );
- wrapper.addVersion( record.getVersion() );
- }
- else
- {
- DependencyWrapper wrapper = new DependencyWrapper( record );
-
- dependees.put( key, wrapper );
- }
- }
-
- return dependees.values();
- }
-
- public static class DependencyWrapper
- {
- private final String groupId;
-
- private final String artifactId;
-
- /**
- * Versions added. We ignore duplicates since you might add those with varying classifiers.
- */
- private Set versions = new HashSet();
-
- private String version;
-
- private String scope;
-
- private String classifier;
-
- public DependencyWrapper( StandardArtifactIndexRecord record )
- {
- this.groupId = record.getGroupId();
-
- this.artifactId = record.getArtifactId();
-
- addVersion( record.getVersion() );
- }
-
- public DependencyWrapper( Dependency dependency )
- {
- this.groupId = dependency.getGroupId();
-
- this.artifactId = dependency.getArtifactId();
-
- this.scope = dependency.getScope();
-
- this.classifier = dependency.getClassifier();
-
- addVersion( dependency.getVersion() );
- }
-
- public String getScope()
- {
- return scope;
- }
-
- public String getClassifier()
- {
- return classifier;
- }
-
- public void addVersion( String version )
- {
- // We use DefaultArtifactVersion to get the correct sorting order later, however it does not have
- // hashCode properly implemented, so we add it here.
- // TODO: add these methods to the actual DefaultArtifactVersion and use that.
- versions.add( new DefaultArtifactVersion( version )
- {
- public int hashCode()
- {
- int result;
- result = getBuildNumber();
- result = 31 * result + getMajorVersion();
- result = 31 * result + getMinorVersion();
- result = 31 * result + getIncrementalVersion();
- result = 31 * result + ( getQualifier() != null ? getQualifier().hashCode() : 0 );
- return result;
- }
-
- public boolean equals( Object o )
- {
- if ( this == o )
- {
- return true;
- }
- if ( o == null || getClass() != o.getClass() )
- {
- return false;
- }
-
- DefaultArtifactVersion that = (DefaultArtifactVersion) o;
-
- if ( getBuildNumber() != that.getBuildNumber() )
- {
- return false;
- }
- if ( getIncrementalVersion() != that.getIncrementalVersion() )
- {
- return false;
- }
- if ( getMajorVersion() != that.getMajorVersion() )
- {
- return false;
- }
- if ( getMinorVersion() != that.getMinorVersion() )
- {
- return false;
- }
- if ( getQualifier() != null ? !getQualifier().equals( that.getQualifier() )
- : that.getQualifier() != null )
- {
- return false;
- }
-
- return true;
- }
- } );
-
- if ( versions.size() == 1 )
- {
- this.version = version;
- }
- else
- {
- this.version = null;
- }
- }
-
- public String getGroupId()
- {
- return groupId;
- }
-
- public String getArtifactId()
- {
- return artifactId;
- }
-
- public List getVersions()
- {
- List versions = new ArrayList( this.versions );
- Collections.sort( versions );
- return versions;
- }
-
- public String getVersion()
- {
- return version;
- }
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.validator;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.xwork.validator.ValidationException;
-import com.opensymphony.xwork.validator.ValidatorContext;
-import com.opensymphony.xwork.validator.validators.ValidatorSupport;
-
-/**
- * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
- */
-public class IntervalValidator
- extends ValidatorSupport
-{
-
- public void validate( Object obj )
- throws ValidationException
- {
- String snapshotsPolicy = (String) getFieldValue( "snapshotsPolicy", obj );
- String releasesPolicy = (String) getFieldValue( "releasesPolicy", obj );
- Integer snapshotsInterval = (Integer) getFieldValue( "snapshotsInterval", obj );
- Integer releasesInterval = (Integer) getFieldValue( "releasesInterval", obj );
-
- ValidatorContext ctxt = getValidatorContext();
-
- if ( !snapshotsPolicy.equals( "interval" ) )
- {
- if ( snapshotsInterval.intValue() != 0 )
- {
- ctxt.addActionError( "Snapshots Interval must be set to zero." );
- }
- }
-
- if ( !releasesPolicy.equals( "interval" ) )
- {
- if ( releasesInterval.intValue() != 0 )
- {
- ctxt.addActionError( "Releases Interval must be set to zero." );
- }
- }
-
- if ( ctxt.hasActionErrors() )
- {
- return;
- }
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.web.validator;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import com.opensymphony.xwork.validator.ValidationException;
-import com.opensymphony.xwork.validator.ValidatorContext;
-import com.opensymphony.xwork.validator.validators.ValidatorSupport;
-
-/**
- * Validator for synced repository form. The values to be validated depends on the
- * selected sync method to be used.
- *
- * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
- */
-public class SyncedRepositoryValidator
- extends ValidatorSupport
-{
-
- public void validate( Object obj )
- throws ValidationException
- {
-
- String method = (String) getFieldValue( "method", obj );
- ValidatorContext ctxt = getValidatorContext();
-
- if ( method.equals( "rsync" ) )
- {
- String rsyncHost = (String) getFieldValue( "rsyncHost", obj );
- if ( rsyncHost == null || rsyncHost.equals( "" ) )
- {
- ctxt.addActionError( "Rsync host is required." );
- }
-
- String rsyncDirectory = (String) getFieldValue( "rsyncDirectory", obj );
- if ( rsyncDirectory == null || rsyncDirectory.equals( "" ) )
- {
- ctxt.addActionError( "Rsync directory is required." );
- }
-
- String rsyncMethod = (String) getFieldValue( "rsyncMethod", obj );
- if ( rsyncMethod == null || rsyncMethod.equals( "" ) )
- {
- ctxt.addActionError( "Rsync method is required." );
- }
- else
- {
- if ( !rsyncMethod.equals( "anonymous" ) && !rsyncMethod.equals( "ssh" ) )
- {
- ctxt.addActionError( "Invalid rsync method" );
- }
- }
-
- String username = (String) getFieldValue( "username", obj );
- if ( username == null || username.equals( "" ) )
- {
- ctxt.addActionError( "Username is required." );
- }
-
- }
- else if ( method.equals( "svn" ) )
- {
- String svnUrl = (String) getFieldValue( "svnUrl", obj );
- if ( svnUrl == null || svnUrl.equals( "" ) )
- {
- ctxt.addActionError( "SVN url is required." );
- }
-
- String username = (String) getFieldValue( "username", obj );
- if ( username == null || username.equals( "" ) )
- {
- ctxt.addActionError( "Username is required." );
- }
- }
- else if ( method.equals( "cvs" ) )
- {
- String cvsRoot = (String) getFieldValue( "cvsRoot", obj );
- if ( cvsRoot == null || cvsRoot.equals( "" ) )
- {
- ctxt.addActionError( "CVS root is required." );
- }
- }
- else if ( method.equals( "file" ) )
- {
- String directory = (String) getFieldValue( "directory", obj );
- if ( directory == null || directory.equals( "" ) )
- {
- ctxt.addActionError( "Directory is required." );
- }
- }
-
- if ( ctxt.hasActionErrors() )
- {
- return;
- }
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<plexus>
- <components>
-
- <component>
- <role>org.codehaus.plexus.registry.Registry</role>
- <implementation>org.codehaus.plexus.registry.commons.CommonsConfigurationRegistry</implementation>
- <role-hint>commons-configuration</role-hint>
- <configuration>
- <properties>
- <system/>
- <jndi prefix="java:comp/env" config-optional="true"/>
- <xml fileName="${user.home}/.m2/archiva.xml" config-optional="true" config-name="org.apache.maven.archiva.user"
- config-at="org.apache.maven.archiva" />
- <xml fileName="${user.home}/.m2/shared.xml" config-optional="true"
- config-name="org.apache.maven.shared.app.user" config-at="org.apache.maven.shared.app"
- config-forceCreate="true"/>
- <properties fileName="${user.home}/.m2/security.properties" config-optional="true"
- config-at="org.codehaus.plexus.security"/>
- <properties fileName="${user.home}/.m2/archiva.properties" config-optional="true"
- config-at="org.codehaus.plexus.security"/>
- <xml fileName="${appserver.base}/conf/archiva.xml" config-optional="true" config-name="org.apache.maven.archiva.base"
- config-at="org.apache.maven.archiva"/>
- <xml fileName="${appserver.base}/conf/shared.xml" config-optional="true"
- config-name="org.apache.maven.shared.app.base" config-at="org.apache.maven.shared.app"/>
- <xml fileName="${appserver.base}/conf/common.xml" config-optional="true"/>
- <properties fileName="${appserver.base}/conf/security.properties" config-optional="true"
- config-at="org.codehaus.plexus.security"/>
- <xml fileName="${appserver.home}/conf/archiva.xml" config-optional="true"
- config-at="org.apache.maven.archiva"/>
- <xml fileName="${appserver.home}/conf/shared.xml" config-optional="true"
- config-at="org.apache.maven.shared.app"/>
- <xml fileName="${appserver.home}/conf/common.xml" config-optional="true"/>
- <properties fileName="${appserver.home}/conf/security.properties" config-optional="true"
- config-at="org.codehaus.plexus.security"/>
- <properties fileName="org/apache/maven/archiva/security.properties" config-at="org.codehaus.plexus.security"/>
- </properties>
- </configuration>
- </component>
-
- <component>
- <role>org.codehaus.plexus.mailsender.MailSender</role>
- <implementation>org.codehaus.plexus.mailsender.javamail.JndiJavamailMailSender</implementation>
- <configuration>
- <jndiSessionName>java:comp/env/mail/Session</jndiSessionName>
- </configuration>
- </component>
-
- <component>
- <role>org.codehaus.plexus.webdav.DavServerManager</role>
- <role-hint>default</role-hint>
- <implementation>org.codehaus.plexus.webdav.DefaultDavServerManager</implementation>
- <description>DefaultDavServerManager</description>
- <configuration>
- <provider-hint>proxied</provider-hint>
- </configuration>
- </component>
-
- <component>
- <role>org.codehaus.plexus.jdo.JdoFactory</role>
- <role-hint>archiva</role-hint>
- <implementation>org.codehaus.plexus.jdo.DataSourceConfigurableJdoFactory</implementation>
- <configuration>
-
- <connectionFactoryName>java:comp/env/jdbc/archiva</connectionFactoryName>
- <shutdownConnectionFactoryName>java:comp/env/jdbc/archivaShutdown</shutdownConnectionFactoryName>
-
- <!-- JPOX and JDO configuration -->
- <persistenceManagerFactoryClass>org.jpox.PersistenceManagerFactoryImpl</persistenceManagerFactoryClass>
- <otherProperties>
- <property>
- <name>org.jpox.autoCreateSchema</name>
- <value>true</value>
- </property>
- <property>
- <name>org.jpox.validateTables</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.validateConstraints</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.validateColumns</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.autoStartMechanism</name>
- <value>None</value>
- </property>
- <property>
- <name>org.jpox.transactionIsolation</name>
- <value>READ_UNCOMMITTED</value>
- </property>
- <property>
- <name>org.jpox.poid.transactionIsolation</name>
- <value>READ_UNCOMMITTED</value>
- </property>
- <property>
- <name>org.jpox.rdbms.dateTimezone</name>
- <value>JDK_DEFAULT_TIMEZONE</value>
- </property>
- <!-- NEEDED FOR POSTGRES, But causes problems in other JDBC implementations.
- <property>
- <name>org.jpox.identifier.case</name>
- <value>PreserveCase</value>
- </property>
- -->
- </otherProperties>
- </configuration>
- </component>
-
- <component>
- <role>org.codehaus.plexus.jdo.JdoFactory</role>
- <role-hint>users</role-hint>
- <implementation>org.codehaus.plexus.jdo.DataSourceConfigurableJdoFactory</implementation>
- <configuration>
-
- <connectionFactoryName>java:comp/env/jdbc/users</connectionFactoryName>
- <shutdownConnectionFactoryName>java:comp/env/jdbc/usersShutdown</shutdownConnectionFactoryName>
-
- <!-- JPOX and JDO configuration -->
- <persistenceManagerFactoryClass>org.jpox.PersistenceManagerFactoryImpl</persistenceManagerFactoryClass>
- <otherProperties>
- <property>
- <name>org.jpox.autoCreateSchema</name>
- <value>true</value>
- </property>
- <property>
- <name>org.jpox.validateTables</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.validateConstraints</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.validateColumns</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.autoStartMechanism</name>
- <value>None</value>
- </property>
- <property>
- <name>org.jpox.transactionIsolation</name>
- <value>READ_UNCOMMITTED</value>
- </property>
- <property>
- <name>org.jpox.poid.transactionIsolation</name>
- <value>READ_UNCOMMITTED</value>
- </property>
- <property>
- <name>org.jpox.rdbms.dateTimezone</name>
- <value>JDK_DEFAULT_TIMEZONE</value>
- </property>
- <!-- NEEDED FOR POSTGRES, But causes problems in other JDBC implementations.
- <property>
- <name>org.jpox.identifier.case</name>
- <value>PreserveCase</value>
- </property>
- -->
- </otherProperties>
- </configuration>
- </component>
-
- <!--
- | Logger manager
- -->
- <component>
- <role>org.codehaus.plexus.logging.LoggerManager</role>
- <implementation>org.codehaus.plexus.logging.slf4j.Slf4jLoggerManager</implementation>
- <lifecycle-handler>basic</lifecycle-handler>
- </component>
- </components>
-
- <load-on-start>
- <component>
- <role>org.apache.maven.archiva.scheduler.RepositoryTaskScheduler</role>
- </component>
- <component>
- <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
- <role-hint>data-refresh</role-hint>
- </component>
- </load-on-start>
-
- <lifecycle-handler-manager implementation="org.codehaus.plexus.lifecycle.DefaultLifecycleHandlerManager">
- <default-lifecycle-handler-id>plexus</default-lifecycle-handler-id>
- <lifecycle-handlers>
- <lifecycle-handler implementation="org.codehaus.plexus.personality.plexus.PlexusLifecycleHandler">
- <id>plexus</id>
- <name>Plexus Lifecycle Handler</name>
- <begin-segment>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.LogEnablePhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.CompositionPhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.ContextualizePhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.AutoConfigurePhase"/>
- <phase implementation="org.codehaus.plexus.registry.RegistryConfigurePhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.ServiceablePhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializePhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.StartPhase"/>
- </begin-segment>
- <suspend-segment>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.SuspendPhase"/>
- </suspend-segment>
- <resume-segment>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.ResumePhase"/>
- </resume-segment>
- <end-segment>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.StopPhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.DisposePhase"/>
- <phase implementation="org.codehaus.plexus.personality.plexus.lifecycle.phase.LogDisablePhase"/>
- </end-segment>
- </lifecycle-handler>
- </lifecycle-handlers>
- </lifecycle-handler-manager>
-</plexus>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
-<taglib>
-
- <tlib-version>2.2.3</tlib-version>
- <jsp-version>1.2</jsp-version>
- <short-name>Archiva Taglib</short-name>
-
- <uri>http://maven.apache.org/archiva</uri>
-
- <display-name>Archiva Taglib</display-name>
- <description><![CDATA[Archiva JSP Taglib]]></description>
-
- <tag>
-
- <name>groupIdLink</name>
- <tag-class>org.apache.maven.archiva.web.tags.GroupIdLinkTag</tag-class>
- <body-content>empty</body-content>
- <description><![CDATA[Render a groupId as a set of Links]]></description>
-
- <attribute>
- <name>var</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
-
- <description><![CDATA[The GroupID String]]></description>
- </attribute>
-
- <attribute>
- <name>includeTop</name>
- <required>false</required>
- <rtexprvalue>true</rtexprvalue>
-
- <description><![CDATA[Boolean indicating if 'top' link should be created or not.]]></description>
- </attribute>
-
- </tag>
-
- <tag>
-
- <name>downloadArtifact</name>
- <tag-class>org.apache.maven.archiva.web.tags.DownloadArtifactTag</tag-class>
- <body-content>empty</body-content>
- <description><![CDATA[Render a a set of download links for an artifact]]></description>
-
- <attribute>
- <name>groupId</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
-
- <description><![CDATA[The GroupID String]]></description>
- </attribute>
-
- <attribute>
- <name>artifactId</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
-
- <description><![CDATA[The ArtifactID String]]></description>
- </attribute>
-
- <attribute>
- <name>version</name>
- <required>true</required>
- <rtexprvalue>true</rtexprvalue>
-
- <description><![CDATA[The Version String]]></description>
- </attribute>
-
- <attribute>
- <name>mini</name>
- <required>false</required>
- <rtexprvalue>true</rtexprvalue>
-
- <description><![CDATA[Boolean indicating if the download link is to be generated in mini format instead.]]></description>
- </attribute>
-
- </tag>
-
-
-</taglib>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
-
- <appender name="rolling" class="org.apache.log4j.DailyRollingFileAppender">
- <param name="file" value="${appserver.base}/logs/archiva.log" />
- <param name="append" value="true" />
- <param name="datePattern" value="'.'yyyy-MM-dd" />
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%-4r [%t] %-5p %c %x - %m%n"/>
- </layout>
- </appender>
-
- <appender name="console" class="org.apache.log4j.ConsoleAppender">
- <param name="Target" value="System.out"/>
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d [%t] %-5p %-30c{1} - %m%n"/>
- </layout>
- </appender>
-
- <!-- Help identify bugs during testing -->
- <logger name="org.apache.maven">
- <level value="info"/>
- </logger>
-
- <logger name="org.codehaus.plexus.security">
- <level value="info"/>
- </logger>
-
- <!-- squelch noisy objects (for now) -->
- <logger name="org.codehaus.plexus.mailsender.MailSender">
- <level value="info"/>
- </logger>
-
- <logger name="org.quartz">
- <level value="info"/>
- </logger>
-
- <logger name="org.apache.jasper">
- <level value="info"/>
- </logger>
-
- <logger name="com.opensymphony.xwork">
- <level value="info"/>
- </logger>
-
- <logger name="com.opensymphony.webwork">
- <level value="info"/>
- </logger>
-
- <logger name="org.codehaus.plexus.PlexusContainer">
- <level value="info"/>
- </logger>
-
- <logger name="JPOX">
- <level value="warn"/>
- </logger>
-
- <logger name="JPOX.MetaData">
- <level value="error"/>
- </logger>
-
- <logger name="JPOX.RDBMS.SQL">
- <level value="error"/>
- </logger>
-
- <logger name="SQL">
- <level value="error"/>
- </logger>
-
- <logger name="freemarker">
- <level value="warn"/>
- </logger>
-
- <logger name="org.codehaus.plexus.component.manager.ClassicSingletonComponentManager">
- <level value="error"/>
- </logger>
-
- <root>
- <priority value ="warn" />
- <appender-ref ref="console" />
- <appender-ref ref="rolling" />
- </root>
-
-</log4j:configuration>
+++ /dev/null
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-#
-
-# --------------------------------------------------------------------
-# Email Settings
-
-# The subject line for the email message.
-email.validation.subject=Welcome to Maven Archiva
-
-# Feedback page
-email.feedback.path=http://maven.apache.org/archiva/mail-lists.html
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="md5">
- <field-validator type="requiredstring">
- <message>
- You must select a file, or enter the checksum. If the file was given and you receive this message,
- there may have been an error generating the checksum.
- </message>
- </field-validator>
- </field>
-</validators>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="q">
- <field-validator type="requiredstring">
- <message>You must enter some search terms.</message>
- </field-validator>
- </field>
-</validators>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="indexPath">
- <field-validator type="requiredstring">
- <message>You must enter the index directory.</message>
- </field-validator>
- </field>
-</validators>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC
- "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="companyPom.groupId">
- <field-validator type="requiredstring">
- <message key="appearance.groupId.required"/>
- </field-validator>
- </field>
- <field name="companyPom.artifactId">
- <field-validator type="requiredstring">
- <message key="appearance.artifactId.required"/>
- </field-validator>
- </field>
-</validators>
\ No newline at end of file
+++ /dev/null
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-#
-
-appearance.groupId.required = You must define a group identifier.
-appearance.artifactId.required = You must define an artifact identifier.
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="id">
- <field-validator type="requiredstring">
- <message>You must enter the repository identifier.</message>
- </field-validator>
- <!--field-validator type="regex">
- <param name="expression"><![CDATA[([A-Z][a-z][0-9])]]></param>
- <message>Id must not have special characters.</message>
- </field-validator-->
- </field>
- <field name="name">
- <field-validator type="requiredstring">
- <message>You must enter the repository name.</message>
- </field-validator>
- </field>
-
- <field name="url">
- <field-validator type="requiredstring">
- <message>You must enter the repository URL.</message>
- </field-validator>
- </field>
- <field name="snapshotsInterval">
- <field-validator type="regex">
- <param name="expression"><![CDATA[([0-9])]]></param>
- <message>The value must be numeric</message>
- </field-validator>
- </field>
- <field name="releasesInterval">
- <field-validator type="regex">
- <param name="expression"><![CDATA[([0-9])]]></param>
- <message>The value must be numeric</message>
- </field-validator>
- </field>
-
- <!-- TODO: is the validation correct? -->
- <validator type="interval">
- <message/>
- </validator>
-
- <field name="layout">
- <field-validator type="required">
- <message>Repository type is required.</message>
- </field-validator>
- <field-validator type="fieldexpression">
- <param name="expression">layout in {"legacy", "default"}</param>
- <message>Invalid repository type.</message>
- </field-validator>
- </field>
- <field name="snapshotsPolicy">
- <field-validator type="fieldexpression">
- <param name="expression">snapshotsPolicy in { "disabled", "daily", "hourly", "never", "interval" }</param>
- <message>Invalid snapshot policy.</message>
- </field-validator>
- </field>
- <field name="releasesPolicy">
- <field-validator type="fieldexpression">
- <param name="expression">releasesPolicy in { "disabled", "daily", "hourly", "never", "interval" }</param>
- <message>Invalid releases policy.</message>
- </field-validator>
- </field>
-
- <field name="managedRepository">
- <field-validator type="requiredstring">
- <message>A managed repository must be selected.</message>
- </field-validator>
- </field>
-
-</validators>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="id">
- <field-validator type="requiredstring">
- <message>You must enter the repository identifier.</message>
- </field-validator>
- </field>
- <field name="urlName">
- <field-validator type="requiredstring">
- <message>You must enter the url name.</message>
- </field-validator>
- </field>
- <field name="name">
- <field-validator type="requiredstring">
- <message>You must enter the repository name.</message>
- </field-validator>
- </field>
- <field name="directory">
- <field-validator type="requiredstring">
- <message>You must enter the repository directory.</message>
- </field-validator>
- </field>
- <field name="layout">
- <field-validator type="fieldexpression">
- <param name="expression">layout in {"legacy", "default"}</param>
- <message>Invalid repository type.</message>
- </field-validator>
- </field>
-</validators>
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="id">
- <field-validator type="requiredstring">
- <message>You must enter the repository identifier.</message>
- </field-validator>
- </field>
- <field name="name">
- <field-validator type="requiredstring">
- <message>You must enter the repository name.</message>
- </field-validator>
- </field>
- <field name="layout">
- <field-validator type="requiredstring">
- <message>Select repository type.</message>
- </field-validator>
- <field-validator type="fieldexpression">
- <param name="expression">layout in {"legacy", "default"}</param>
- <message>Invalid repository type.</message>
- </field-validator>
- </field>
- <field name="managedRepository">
- <field-validator type="requiredstring">
- <message>A managed repository must be selected.</message>
- </field-validator>
- </field>
-
- <validator type="syncedrepo">
- <message/>
- </validator>
-
-</validators>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="method">
- <field-validator type="requiredstring">
- <message>You must enter the synchronization method.</message>
- </field-validator>
- <field-validator type="fieldexpression">
- <param name="expression">method in { "rsync", "cvs", "svn", "file" }</param>
- <message>Invalid method.</message>
- </field-validator>
- </field>
-</validators>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<validators>
- <validator name="required" class="com.opensymphony.xwork.validator.validators.RequiredFieldValidator"/>
- <validator name="requiredstring" class="com.opensymphony.xwork.validator.validators.RequiredStringValidator"/>
- <validator name="int" class="com.opensymphony.xwork.validator.validators.IntRangeFieldValidator"/>
- <validator name="double" class="com.opensymphony.xwork.validator.validators.DoubleRangeFieldValidator"/>
- <validator name="date" class="com.opensymphony.xwork.validator.validators.DateRangeFieldValidator"/>
- <validator name="expression" class="com.opensymphony.xwork.validator.validators.ExpressionValidator"/>
- <validator name="fieldexpression" class="com.opensymphony.xwork.validator.validators.FieldExpressionValidator"/>
- <validator name="email" class="com.opensymphony.xwork.validator.validators.EmailValidator"/>
- <validator name="url" class="com.opensymphony.xwork.validator.validators.URLValidator"/>
- <validator name="visitor" class="com.opensymphony.xwork.validator.validators.VisitorFieldValidator"/>
- <validator name="conversion" class="com.opensymphony.xwork.validator.validators.ConversionErrorFieldValidator"/>
- <validator name="stringlength" class="com.opensymphony.xwork.validator.validators.StringLengthFieldValidator"/>
- <validator name="regex" class="com.opensymphony.xwork.validator.validators.RegexFieldValidator"/>
- <validator name="interval" class="org.apache.maven.archiva.web.validator.IntervalValidator"/>
- <validator name="syncedrepo" class="org.apache.maven.archiva.web.validator.SyncedRepositoryValidator"/>
-</validators>
-
+++ /dev/null
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-#
-
-# define our own action mapper here
-webwork.mapper.class = org.apache.maven.archiva.web.mapper.RepositoryActionMapper
-webwork.objectFactory = org.codehaus.plexus.xwork.PlexusObjectFactory
-webwork.url.includeParams = none
-
-# TODO: package up a theme and share with Continuum. Should contain everything from xhtml, and set templateDir to WEB-INF/themes
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1//EN"
- "http://www.opensymphony.com/xwork/xwork-1.1.dtd">
-
-<xwork>
- <!-- TODO: better error handling for exceptions needed! -->
- <include file="webwork-default.xml"/>
-
- <!-- Include plexus-security xwork configurations. -->
- <include file="xwork-security.xml"/>
-
- <package name="base" extends="webwork-default">
- <interceptors>
- <interceptor name="configuration" class="configurationInterceptor"/>
- <interceptor name="pssForceAdminUser" class="pssForceAdminUserInterceptor"/>
- <interceptor name="pssSecureActions" class="pssSecureActionInterceptor"/>
- <interceptor name="pssAutoLogin" class="pssAutoLoginInterceptor"/>
- <interceptor name="pssEnvironmentChecker" class="pssEnvironmentCheckInterceptor"/>
- <interceptor name="pssPolicyEnforcement" class="pssPolicyEnforcementInterceptor"/>
-
- <interceptor-stack name="unconfiguredStack">
- <interceptor-ref name="defaultStack"/>
- <interceptor-ref name="pssEnvironmentChecker"/>
- <interceptor-ref name="pssForceAdminUser"/>
- <interceptor-ref name="pssAutoLogin"/>
- <interceptor-ref name="pssPolicyEnforcement"/>
- <interceptor-ref name="pssSecureActions"/>
- </interceptor-stack>
-
- <interceptor-stack name="configuredStack">
- <interceptor-ref name="defaultStack"/>
- <interceptor-ref name="pssEnvironmentChecker"/>
- <interceptor-ref name="pssForceAdminUser"/>
- <interceptor-ref name="pssAutoLogin"/>
- <interceptor-ref name="pssPolicyEnforcement"/>
- <interceptor-ref name="pssSecureActions"/>
- <interceptor-ref name="configuration"/>
- </interceptor-stack>
-
- <interceptor-stack name="configuredPrepareParamsStack">
- <interceptor-ref name="paramsPrepareParamsStack"/>
- <interceptor-ref name="configuredStack"/>
- </interceptor-stack>
- </interceptors>
-
- <!-- Default interceptor stack. -->
- <default-interceptor-ref name="configuredStack"/>
-
- <global-results>
- <!-- TODO: want an extra message on the configure page when this first happens! -->
- <!-- TODO: can we send them back to the original location afterwards? -->
- <result name="config-needed" type="redirect-action">
- <param name="namespace">/admin</param>
- <param name="actionName">configure</param>
- </result>
-
- <!-- This redirect is triggered by the configuration interceptor -->
- <result name="config-repository-needed" type="redirect-action">
- <param name="namespace">/admin</param>
- <param name="actionName">addRepository</param>
- <param name="method">input</param>
- </result>
-
- <!-- The following security-* result names arrive from the plexus-security package -->
- <result name="security-login-success" type="redirect-action">index</result>
- <result name="security-login-cancel" type="redirect-action">index</result>
- <result name="security-login-locked" type="redirect-action">
- <param name="infoMessage">Account Locked</param>
- <param name="actionName">index</param>
- </result>
- <result name="security-logout" type="redirect-action">index</result>
- <result name="requires-authentication" type="redirect-action">
- <param name="actionName">login</param>
- <param name="namespace">/security</param>
- </result>
- <result name="requires-authorization" type="redirect-action">
- <param name="actionName">login</param>
- <param name="namespace">/security</param>
- </result>
- <result name="security-register-success" type="redirect-action">
- <param name="actionName">login</param>
- <param name="namespace">/security</param>
- </result>
- <result name="security-register-cancel" type="redirect-action">
- <param name="actionName">login</param>
- <param name="namespace">/security</param>
- </result>
- <result name="security-account-success" type="redirect-action">index</result>
- <result name="security-account-cancel" type="redirect-action">
- <param name="actionName">login</param>
- <param name="namespace">/security</param>
- </result>
- <result name="security-admin-user-created" type="redirect-action">
- <param name="actionName">login</param>
- <param name="namespace">/security</param>
- </result>
- <result name="security-admin-user-needed" type="redirect-action">
- <param name="actionName">addadmin</param>
- <param name="namespace">/security</param>
- </result>
- <result name="security-must-change-password" type="redirect-action">
- <param name="actionName">password</param>
- <param name="namespace">/security</param>
- </result>
-
- <!-- Generic Catchall for those action configurations that forget to
- include a result for 'error' -->
- <result name="error">/WEB-INF/jsp/generalError.jsp</result>
- </global-results>
- </package>
-
- <!-- Configuration for the default package. -->
- <package name="default" extends="base" namespace="/">
-
- <!-- This is the redirection facility for plexus-security,
- allowing plexus-security to call out from its own set of actions
- into the application webapp, using global result names. -->
- <action name="pssRedirect" class="pss-redirect" method="redirect">
- <result type="redirect-action">browse</result>
- </action>
-
- <action name="index" class="searchAction" method="input">
- <result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
- </action>
-
- <action name="quickSearch" class="searchAction" method="quickSearch">
- <result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
- <result>/WEB-INF/jsp/results.jsp</result>
- <result name="error">/WEB-INF/jsp/quickSearch.jsp</result>
- </action>
-
- <action name="findArtifact" class="searchAction" method="input">
- <result name="input">/WEB-INF/jsp/findArtifact.jsp</result>
- </action>
-
- <action name="checksumSearch" class="searchAction" method="findArtifact">
- <result name="input">/WEB-INF/jsp/findArtifact.jsp</result>
- <result name="results">/WEB-INF/jsp/results.jsp</result>
- <result name="error">/WEB-INF/jsp/findArtifact.jsp</result>
- <result name="artifact" type="redirect">
- /browse/${searchResults[0].groupId}/${searchResults[0].artifactId}/${searchResults[0].version}
- </result>
- </action>
-
- <action name="browse" class="browseAction" method="browse">
- <result>/WEB-INF/jsp/browse.jsp</result>
- </action>
-
- <action name="browseGroup" class="browseAction" method="browseGroup">
- <result>/WEB-INF/jsp/browseGroup.jsp</result>
- </action>
-
- <action name="browseArtifact" class="browseAction" method="browseArtifact">
- <result>/WEB-INF/jsp/browseArtifact.jsp</result>
- </action>
-
- <action name="showArtifact" class="showArtifactAction" method="artifact">
- <result>/WEB-INF/jsp/showArtifact.jsp</result>
- </action>
-
- <action name="showArtifactMailingLists" class="showArtifactAction" method="mailingLists">
- <result>/WEB-INF/jsp/showArtifact.jsp</result>
- </action>
-
- <action name="showArtifactReports" class="showArtifactAction" method="reports">
- <result>/WEB-INF/jsp/showArtifact.jsp</result>
- </action>
-
- <action name="showArtifactDependencies" class="showArtifactAction" method="dependencies">
- <result>/WEB-INF/jsp/showArtifact.jsp</result>
- </action>
-
- <action name="showArtifactDependees" class="showArtifactAction" method="dependees">
- <result>/WEB-INF/jsp/showArtifact.jsp</result>
- </action>
-
- <action name="showArtifactDependencyTree" class="showArtifactAction" method="dependencyTree">
- <result>/WEB-INF/jsp/showArtifact.jsp</result>
- </action>
-
- </package>
-
- <package name="components" namespace="/components" extends="webwork-default">
- <default-interceptor-ref name="basicStack"/>
- <action name="companyInfo" class="companyInfo">
- <result>/WEB-INF/jsp/components/companyLogo.jsp</result>
- </action>
- </package>
-
- <!-- Configuration for the admin package. -->
- <package name="admin" namespace="/admin" extends="base">
-
- <action name="index" class="configureAction" method="input">
- <result name="input">/WEB-INF/jsp/admin/index.jsp</result>
- </action>
-
- <action name="managedRepositories" class="configureAction" method="input">
- <result name="input">/WEB-INF/jsp/admin/managedRepositories.jsp</result>
- </action>
-
- <action name="addRepository" class="configureRepositoryAction" method="add">
- <result name="input">/WEB-INF/jsp/admin/addRepository.jsp</result>
- <result type="redirect-action">managedRepositories</result>
- <interceptor-ref name="unconfiguredStack"/>
- </action>
-
- <action name="editRepository" class="configureRepositoryAction" method="edit">
- <result name="input">/WEB-INF/jsp/admin/editRepository.jsp</result>
- <result type="redirect-action">managedRepositories</result>
- <interceptor-ref name="configuredPrepareParamsStack"/>
- </action>
-
- <action name="deleteRepository" class="deleteRepositoryAction">
- <result name="input">/WEB-INF/jsp/admin/deleteRepository.jsp</result>
- <result type="redirect-action">managedRepositories</result>
- </action>
-
- <action name="proxiedRepositories" class="configureAction" method="input">
- <result name="input">/WEB-INF/jsp/admin/proxiedRepositories.jsp</result>
- </action>
-
- <action name="addProxiedRepository" class="configureProxiedRepositoryAction" method="add">
- <result name="input">/WEB-INF/jsp/admin/addProxiedRepository.jsp</result>
- <result type="redirect-action">proxiedRepositories</result>
- </action>
-
- <action name="editProxiedRepository" class="configureProxiedRepositoryAction" method="edit">
- <result name="input">/WEB-INF/jsp/admin/editProxiedRepository.jsp</result>
- <result type="redirect-action">proxiedRepositories</result>
- <interceptor-ref name="configuredPrepareParamsStack"/>
- </action>
-
- <action name="deleteProxiedRepository" class="deleteProxiedRepositoryAction">
- <result name="input">/WEB-INF/jsp/admin/deleteProxiedRepository.jsp</result>
- <result type="redirect-action">proxiedRepositories</result>
- </action>
-
- <action name="syncedRepositories" class="configureAction" method="input">
- <result name="input">/WEB-INF/jsp/admin/syncedRepositories.jsp</result>
- </action>
-
- <action name="addSyncedRepository" class="configureSyncedRepositoryAction">
- <result name="input">/WEB-INF/jsp/admin/selectSyncedRepository.jsp</result>
- <result type="chain">
- <param name="actionName">addSelectedSyncedRepository</param>
- <param name="method">input</param>
- </result>
- </action>
-
- <action name="addSelectedSyncedRepository" class="configureSyncedRepositoryAction" method="add">
- <result name="input">/WEB-INF/jsp/admin/addSyncedRepository.jsp</result>
- <result type="redirect-action">syncedRepositories</result>
- </action>
-
- <action name="editSyncedRepository" class="configureSyncedRepositoryAction" method="edit">
- <result name="input">/WEB-INF/jsp/admin/editSyncedRepository.jsp</result>
- <result type="redirect-action">syncedRepositories</result>
- <interceptor-ref name="configuredPrepareParamsStack"/>
- </action>
-
- <action name="deleteSyncedRepository" class="deleteSyncedRepositoryAction">
- <result name="input">/WEB-INF/jsp/admin/deleteSyncedRepository.jsp</result>
- <result type="redirect-action">syncedRepositories</result>
- </action>
-
- <action name="configure" class="configureAction" method="input">
- <result name="input">/WEB-INF/jsp/admin/configure.jsp</result>
- <interceptor-ref name="unconfiguredStack"/>
- </action>
-
- <action name="saveConfiguration" class="configureAction">
- <result name="input">/WEB-INF/jsp/admin/configure.jsp</result>
- <result>/WEB-INF/jsp/admin/index.jsp</result>
- <interceptor-ref name="unconfiguredStack"/>
- </action>
-
- <action name="runIndexer" class="runRepositoryTaskAction" method="runRefresh">
- <result type="redirect-action">index</result>
- </action>
-
- <action name="reports" class="reportsAction">
- <result>/WEB-INF/jsp/reports/reports.jsp</result>
- </action>
-
- <action name="runReport" class="reportsAction" method="runReport">
- <interceptor-ref name="configuredStack"/>
- <interceptor-ref name="execAndWait"/>
- <result name="wait" type="redirect">/admin/reports.action?reportGroup=${reportGroup}&repositoryId=${repositoryId}&filter=${filter}</result>
- <result name="success" type="redirect">/admin/reports.action?reportGroup=${reportGroup}&repositoryId=${repositoryId}&filter=${filter}</result>
- </action>
-
- <action name="configureAppearance" class="configureAppearance" method="input">
- <result name="input">/WEB-INF/jsp/admin/appearance.jsp</result>
- </action>
-
- <action name="editAppearance" class="configureAppearance" method="input">
- <result name="input">/WEB-INF/jsp/admin/editAppearance.jsp</result>
- </action>
-
- <action name="saveAppearance" class="configureAppearance">
- <result name="input">/WEB-INF/jsp/admin/editAppearance.jsp</result>
- <result type="redirect-action">
- <param name="actionName">configureAppearance</param>
- <param name="namespace">/admin</param>
- </result>
- </action>
-
- <action name="editCompanyPom" class="editPom" method="input">
- <result name="input">/WEB-INF/jsp/admin/editPom.jsp</result>
- </action>
-
- <action name="saveCompanyPom" class="editPom">
- <result name="input">/WEB-INF/jsp/admin/editPom.jsp</result>
- <result type="redirect-action">
- <param name="actionName">configureAppearance</param>
- <param name="namespace">/admin</param>
- </result>
- </action>
- </package>
-</xwork>
-
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<decorators defaultdir="/WEB-INF/jsp/decorators">
- <excludes>
- <pattern>/repository/*</pattern>
- <pattern>/components/*</pattern>
- </excludes>
-
- <decorator name="default" page="default.jsp">
- <pattern>/*</pattern>
- </decorator>
-</decorators>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Add Proxied Repository</h2>
-
- <%@ include file="errorMessages.jsp" %>
-
- <ww:actionmessage/>
- <ww:form method="post" action="addProxiedRepository" namespace="/admin" validate="true">
- <ww:textfield name="id" label="Identifier" size="10"/>
- <%@ include file="/WEB-INF/jsp/admin/include/proxiedRepositoryForm.jspf" %>
-
- <ww:submit value="Add Repository"/>
- </ww:form>
-
- <script type="text/javascript">
- document.getElementById("addProxiedRepository_id").focus();
- </script>
-
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Add Managed Repository</h2>
-
- <ww:actionmessage/>
- <ww:form method="post" action="addRepository" namespace="/admin" validate="true">
- <ww:textfield name="id" label="Identifier" size="10" required="true"/>
- <%@ include file="/WEB-INF/jsp/admin/include/managedRepositoryForm.jspf" %>
- <ww:checkbox name="indexed" fieldValue="true" value="true" label="Indexed"/>
- <ww:submit value="Add Repository"/>
- </ww:form>
-
- <script type="text/javascript">
- document.getElementById("addRepository_id").focus();
- </script>
-
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Add Synced Repository</h2>
-
- <%@ include file="errorMessages.jsp" %>
-
- <ww:actionmessage/>
- <ww:form method="post" action="addSelectedSyncedRepository" namespace="/admin" validate="true">
- <ww:textfield name="id" label="Identifier" size="10" required="true"/>
- <%@ include file="/WEB-INF/jsp/admin/include/syncedRepositoryForm.jspf" %>
-
- <ww:submit value="Add Repository"/>
- </ww:form>
-
- <script type="text/javascript">
- document.getElementById("addSelectedSyncedRepository_id").focus();
- </script>
-
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<html>
-<head>
- <title>Configure Appearance</title>
- <ww:head/>
-</head>
-
-<body>
-<h1>Appearance</h1>
-
-<div style="float: right">
- <a href="<ww:url action='editAppearance' />">Edit</a>
-</div>
-<h2>Company Details</h2>
-
-<p>
- The logo in the top right of the screen is controlled by your selected 'company POM'.
-</p>
-
-<ww:set name="companyPom" value="companyPom"/>
-
-<c:if test="${empty(companyPom.groupId) || empty(companyPom.artifactId)}">
- <p>
- You have not yet specified a company POM. <a href="<ww:url action='editAppearance' />">Select a Company POM</a>
- </p>
-</c:if>
-
-<c:if test="${!empty(companyPom.groupId) && !empty(companyPom.artifactId)}">
- <p>
- Your selected company POM is below. If you would like to change the organization name, url or logo, you can
- <a href="<ww:url action='editCompanyPom'/>">edit the POM</a>.
- </p>
-
- <ww:set name="companyModel" value="companyModel"/>
- <table>
- <ww:label name="companyPom.groupId" label="Group ID"/>
- <ww:label name="companyPom.artifactId" label="Artifact ID"/>
- <c:if test="${companyModel != null}">
- <ww:label name="companyModel.version" label="Version"/>
- </c:if>
- </table>
-
- <div style="float: right">
- <a href="<ww:url action='editCompanyPom' />">Edit Company POM</a>
- </div>
- <h3>POM Information</h3>
-
- <c:choose>
- <c:when test="${companyModel != null}">
- <table>
- <tr>
- <th>Name</th>
- <td>${companyModel.organization.name}</td>
- </tr>
- <tr>
- <th>URL</th>
- <td><a href="${companyModel.organization.url}">
- <code>${companyModel.organization.url}</code>
- </a></td>
- </tr>
- <tr>
- <th>Logo URL</th>
- <td>
- <code>${companyModel.properties['organization.logo']}</code>
- </td>
- </tr>
- </table>
- </c:when>
- <c:otherwise>
- Company POM '${companyPom.groupId}:${companyPom.artifactId}' doesn't exist.
- <a href="<ww:url action='editCompanyPom' />">Create company POM</a>
- </c:otherwise>
- </c:choose>
-</c:if>
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div class="errors">
- <ww:actionerror/>
-</div>
-
-<div id="contentArea">
- <ww:actionmessage/>
- <ww:form method="post" action="saveConfiguration" namespace="/admin" validate="true">
- <ww:textfield name="indexPath" label="Index Directory" size="100" required="true"/>
- <!--ww:textfield name="indexerCronExpression" label="Indexing Schedule"/-->
-
- <ww:label value="Indexing Schedule" labelposition="top"/>
- <ww:div>
- <ww:textfield name="second" label="Second" size="2"/>
- <ww:textfield name="minute" label="Minute" labelposition="left" size="2"/>
- <ww:textfield name="hour" label="Hour" size="2"/>
- <ww:textfield name="dayOfMonth" label="Day Of Month" size="2"/>
- <ww:textfield name="month" label="Month" size="2"/>
- <ww:textfield name="dayOfWeek" label="Day Of Week" size="2"/>
- <ww:textfield name="year" label="Year" size="4"/>
- </ww:div>
-
- <ww:hidden name="proxy.protocol" value="http"/>
- <ww:textfield name="proxy.host" label="HTTP Proxy Host"/>
- <ww:textfield name="proxy.port" label="HTTP Proxy Port"/>
- <ww:textfield name="proxy.username" label="HTTP Proxy Username"/>
- <ww:password name="proxy.password" label="HTTP Proxy Password"/>
-
- <ww:submit value="Save Configuration"/>
-
- <ww:div>
- <ww:label value="Indexing Schedule Keys:" labelposition="top"/>
- <ww:label value="* = every" labelposition="top"/>
- <ww:label value="? = any" labelposition="top"/>
- <ww:label value="- = ranges" labelposition="top"/>
- <ww:label value="/ = increments" labelposition="top"/>
- </ww:div>
- </ww:form>
-
- <ww:div>
- <p><i>For valid cron expression values for the Indexing Schedule, see
- <ww:a href="http://www.opensymphony.com/quartz/api/org/quartz/CronExpression.html">here</ww:a>
- </i></p>
- </ww:div>
-
- <script type="text/javascript">
- document.getElementById("saveConfiguration_indexPath").focus();
- </script>
-
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Delete Proxied Repository</h2>
-
- <blockquote>
- <strong><span class="statusFailed">WARNING:</span> This operation can not be undone.</strong>
- </blockquote>
-
- <ww:form method="post" action="deleteProxiedRepository" namespace="/admin" validate="true">
- <ww:hidden name="repoId"/>
- <ww:radio list="#@java.util.LinkedHashMap@{
- 'delete-contents' : 'Remove the repository and delete its contents from managed repositories',
- 'delete-entry' : 'Remove the repository from the available list, but leave the contents in the managed repositories',
- 'unmodified' : 'Leave the repository unmodified'}" name="operation" theme="archiva"/>
- <ww:submit value="Go"/>
- </ww:form>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Delete Managed Repository</h2>
-
- <blockquote>
- <strong><span class="statusFailed">WARNING:</span> This operation can not be undone.</strong>
- </blockquote>
-
- <ww:form method="post" action="deleteRepository" namespace="/admin" validate="true">
- <ww:hidden name="repoId"/>
- <ww:radio list="#@java.util.LinkedHashMap@{'delete-contents' : 'Remove the repository and delete its contents from disk',
- 'delete-entry' : 'Remove the repository from the management list, but leave the contents unmodified',
- 'unmodified' : 'Leave the repository unmodified'}" name="operation" theme="archiva"/>
- <ww:submit value="Go"/>
- </ww:form>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Delete Synced Repository</h2>
-
- <blockquote>
- <strong><span class="statusFailed">WARNING:</span> This operation can not be undone.</strong>
- </blockquote>
-
- <ww:form method="post" action="deleteSyncedRepository" namespace="/admin" validate="true">
- <ww:hidden name="repoId"/>
- <ww:radio list="#@java.util.LinkedHashMap@{
- 'delete-contents' : 'Remove the repository and delete its contents from managed repositories',
- 'delete-entry' : 'Remove the repository from the available list, but leave the contents in the managed repositories',
- 'unmodified' : 'Leave the repository unmodified'}" name="operation" theme="archiva"/>
- <ww:submit value="Go"/>
- </ww:form>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<html>
-<head>
- <title>Configure Appearance</title>
- <ww:head/>
-</head>
-
-<body>
-<h1>Appearance</h1>
-
-<h2>Company Details</h2>
-
-<p>
- Enter the details of the company super POM below. If it exists, the organization name, URL and logo will be read
- from it.
-</p>
-
-<ww:actionmessage/>
-<ww:form method="post" action="saveAppearance" namespace="/admin" validate="true" theme="xhtml">
- <ww:textfield name="companyPom.groupId" label="Group ID"/>
- <ww:textfield name="companyPom.artifactId" label="Artifact ID"/>
- <ww:submit value="Save"/>
-</ww:form>
-</body>
-
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<html>
-<head>
- <title>Edit Company POM</title>
- <ww:head/>
-</head>
-
-<body>
-<h1>Company POM</h1>
-
-<ww:actionmessage/>
-<ww:form method="post" action="saveCompanyPom" namespace="/admin" validate="true" theme="xhtml">
- <ww:label name="companyModel.groupId" label="Group ID"/>
- <ww:label name="companyModel.artifactId" label="Artifact ID"/>
- <tr>
- <td>Version</td>
- <td>
- <ww:property value="companyModel.version"/>
- <i>(The version will automatically be incremented when you save this form)</i>
- </td>
- </tr>
- <tr>
- <td></td>
- <td><h2>Organization</h2></td>
- </tr>
- <ww:textfield name="companyModel.organization.name" size="40" label="Name"/>
- <ww:textfield name="companyModel.organization.url" size="70" label="URL"/>
- <%-- TODO: how to get it to be a string, not a String[]? --%>
- <ww:textfield name="companyModel.properties['organization.logo']" size="70" label="Logo URL"/>
- <ww:submit value="Save"/>
-</ww:form>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Edit Proxied Repository</h2>
-
- <%@ include file="errorMessages.jsp" %>
-
- <ww:actionmessage/>
- <ww:form method="post" action="editProxiedRepository" namespace="/admin" validate="true">
- <ww:hidden name="id"/>
- <%@ include file="/WEB-INF/jsp/admin/include/proxiedRepositoryForm.jspf" %>
- <ww:submit value="Update Repository"/>
- </ww:form>
-
- <script type="text/javascript">
- document.getElementById("editProxiedRepository_name").focus();
- </script>
-
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Edit Managed Repository</h2>
-
- <ww:actionmessage/>
- <ww:form method="post" action="editRepository" namespace="/admin" validate="true">
- <ww:hidden name="id"/>
- <%@ include file="/WEB-INF/jsp/admin/include/managedRepositoryForm.jspf" %>
- <ww:checkbox name="indexed" fieldValue="true" label="Indexed"/>
- <ww:submit value="Update Repository"/>
- </ww:form>
-
- <script type="text/javascript">
- document.getElementById("editRepository_name").focus();
- </script>
-
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Edit Synced Repository</h2>
-
- <%@ include file="errorMessages.jsp" %>
-
- <ww:actionmessage/>
- <ww:form method="post" action="editSyncedRepository" namespace="/admin" validate="true">
- <ww:hidden name="id"/>
- <%@ include file="/WEB-INF/jsp/admin/include/syncedRepositoryForm.jspf" %>
-
- <ww:submit value="Update Repository"/>
- </ww:form>
-
- <script type="text/javascript">
- document.getElementById("editSyncedRepository_name").focus();
- </script>
-
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<p>
- <ww:if test="hasActionErrors()">
- <b style="color: red;">Errors:</b>
- <ww:iterator value="actionErrors">
- <li style="color: red;">
- <ww:property/>
- </li>
- </ww:iterator>
- </ww:if>
-</p>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-<c:set var="urlbase">${pageContext.request.scheme}://${pageContext.request.serverName}
- :${pageContext.request.serverPort}${pageContext.request.contextPath}/repository/
-</c:set>
-
-<tr>
- <td>
- <ww:label for="urlName" theme="simple">URL Name*:</ww:label>
- </td>
- <td>
- <c:out value="${urlbase}"/>
- <ww:textfield name="urlName" id="urlName" size="20" theme="simple" required="true"/>
- </td>
-</tr>
-
-<ww:textfield name="name" label="Name" size="50" required="true"/>
-<ww:textfield name="directory" label="Directory" size="100" required="true"/>
-<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
- name="layout" label="Type"/>
-<ww:checkbox name="includeSnapshots" fieldValue="true" label="Snapshots Included"/>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<ww:textfield name="name" label="Name" size="50" required="true"/>
-<ww:textfield name="url" label="URL" size="50" required="true"/>
-<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
- name="layout" label="Type"/>
-<ww:select name="snapshotsPolicy" label="Snapshots" list="#@java.util.LinkedHashMap@{
- 'disabled' : 'Disabled',
- 'daily' : 'Enabled, updated daily',
- 'hourly' : 'Enabled, updated hourly',
- 'never' : 'Enabled, never updated',
- 'interval' : 'Enabled, updated on given interval'}"/>
-<ww:textfield label="Snapshot update interval" name="snapshotsInterval" size="4"/>
-<ww:select name="releasesPolicy" label="Releases" list="#@java.util.LinkedHashMap@{
- 'disabled' : 'Disabled',
- 'daily' : 'Enabled, updated daily',
- 'hourly' : 'Enabled, updated hourly',
- 'never' : 'Enabled, never updated',
- 'interval' : 'Enabled, updated on given interval'}"/>
-<ww:textfield label="Release update interval" name="releasesInterval" size="4"/>
-<ww:select list="configuration.repositoriesMap" name="managedRepository" label="Proxied through"/>
-<ww:checkbox name="useNetworkProxy" fieldValue="true" label="Use HTTP Proxy"/>
-<ww:checkbox name="cacheFailures" fieldValue="true" label="Cache Failures"/>
-<ww:checkbox name="hardFail" fieldValue="true" label="Fail Whole Group"/>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<ww:hidden name="method"/>
-<ww:textfield name="name" label="Name" size="50"/>
-<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
- name="layout" label="Type"/>
-<ww:select list="configuration.repositoriesMap" name="managedRepository" label="Synced to"/>
-<ww:textfield name="cronExpression" label="Schedule"/>
-
-<ww:set name="method" value="method"/>
-<c:choose>
- <c:when test="${method == 'cvs'}">
- <ww:textfield name="properties['cvsRoot']" label="CVS Root" size="100"/>
- </c:when>
- <c:when test="${method == 'svn'}">
- <ww:textfield name="properties['svnUrl']" label="Subversion URL" size="100"/>
- <ww:textfield name="properties['username']" label="Subversion Username" size="30"/>
- </c:when>
- <c:when test="${method == 'rsync'}">
- <ww:textfield name="properties['rsyncHost']" label="Rsync Host"/>
- <ww:textfield name="properties['rsyncDirectory']" label="Rsync Directory" size="100"/>
- <ww:select name="properties['rsyncMethod']" label="Rsync Method"
- list="#@java.util.LinkedHashMap@{'rsync' : 'Anonymous', 'ssh' : 'SSH'}"/>
- <ww:textfield name="properties['username']" label="Rsync Username" size="30"/>
- </c:when>
- <c:when test="${method == 'file'}">
- <ww:textfield name="properties['directory']" label="Directory" size="100"/>
- </c:when>
-</c:choose>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
-
-<html>
-<head>
- <title>Administration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Administration</h1>
-
-<div id="contentArea">
- <div>
- <div style="float: right">
- <%-- TODO replace with icons --%>
- <pss:ifAuthorized permission="archiva-manage-configuration">
- <a href="<ww:url action="configure" />">Edit Configuration</a>
- </pss:ifAuthorized>
- </div>
- <h2>Configuration</h2>
- </div>
-
- <table class="infoTable">
- <tr>
- <th>Index Directory</th>
- <td>
- <ww:property value="indexPath"/>
- </td>
- <td></td>
- </tr>
- <tr>
- <th>Indexing Schedule</th>
- <td>
- <ww:property value="indexerCronExpression"/>
- </td>
- <%-- TODO: a "delete index and run now" operation should be here too (really clean, remove deletions that didn't get picked up) --%>
- </tr>
- <tr>
- <th>Last Indexing Time</th>
- <td>
- <ww:property value="lastIndexingTime"/>
- </td>
- <td></td>
- </tr>
- </table>
-
- <table class="infoTable">
- <tr>
- <td>
- <pss:ifAuthorized permission="archiva-run-indexer">
- <a href="<ww:url action="runIndexer" />">Run Now</a>
- </pss:ifAuthorized>
- </td>
- </tr>
- </table>
-
- <ww:set name="proxy" value="proxy"/>
- <c:if test="${!empty(proxy.host)}">
- <h3>HTTP Proxy</h3>
-
- <table class="infoTable">
- <tr>
- <th>Host</th>
- <td>${proxy.host}</td>
- </tr>
- <tr>
- <th>Port</th>
- <td>${proxy.port}</td>
- </tr>
- <tr>
- <th>Username</th>
- <td>${proxy.username}</td>
- </tr>
- </table>
- </c:if>
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
-
-<html>
-<head>
- <title>Administration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Administration</h1>
-
-<div id="contentArea">
-
-<%-- DO NOT REFORMAT THIS LINE --%>
-<c:set var="urlbase">${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/repository/</c:set>
-
-<div>
- <div style="float: right">
- <%-- TODO replace with icons --%>
- <pss:ifAuthorized permission="archiva-manage-configuration">
- <ww:url id="addRepositoryUrl" action="addRepository" method="input"/>
- <ww:a href="%{addRepositoryUrl}">Add Repository</ww:a>
- </pss:ifAuthorized>
- </div>
- <h2>Managed Repositories</h2>
-</div>
-
-<ww:set name="repositories" value="repositories"/>
-<c:if test="${empty(repositories)}">
- <strong>There are no managed repositories configured yet.</strong>
-</c:if>
-<c:forEach items="${repositories}" var="repository" varStatus="i">
-
- <div>
- <div style="float: right">
- <pss:ifAnyAuthorized permissions="archiva-manage-configuration">
- <ww:url id="editRepositoryUrl" action="editRepository" method="input">
- <ww:param name="repoId" value="%{'${repository.id}'}"/>
- </ww:url>
- <ww:url id="deleteRepositoryUrl" action="deleteRepository" method="input">
- <ww:param name="repoId" value="%{'${repository.id}'}"/>
- </ww:url>
- <%-- TODO replace with icons --%>
- <ww:a href="%{editRepositoryUrl}">Edit Repository</ww:a>
- <ww:a href="%{deleteRepositoryUrl}">Delete Repository</ww:a>
- </pss:ifAnyAuthorized>
- </div>
- <h3>${repository.name}</h3>
- <table class="infoTable">
- <tr>
- <th>Identifier</th>
- <td>
- <code>${repository.id}</code>
- </td>
- </tr>
- <tr>
- <th>Directory</th>
- <td>${repository.directory}</td>
- </tr>
- <tr>
- <th>WebDAV URL</th>
- <td><a href="${urlbase}${repository.urlName}/">${urlbase}${repository.urlName}/</a></td>
- </tr>
- <tr>
- <th>Type</th>
- <%-- TODO: can probably just use layout appended to a key prefix in i18n to simplify this --%>
- <td>
- <c:choose>
- <c:when test="${repository.layout == 'default'}">
- Maven 2.x Repository
- </c:when>
- <c:otherwise>
- Maven 1.x Repository
- </c:otherwise>
- </c:choose>
- </td>
- </tr>
- <tr>
- <th>Snapshots Included</th>
- <td class="${repository.includeSnapshots ? 'donemark' : 'errormark'} booleanIcon"> ${repository.includeSnapshots}</td>
- </tr>
- <tr>
- <th>Indexed</th>
- <td class="${repository.indexed ? 'donemark' : 'errormark'} booleanIcon"> ${repository.indexed}</td>
- </tr>
- <tr>
- <th>POM Snippet</th>
- <td><a href="#" onclick="Effect.toggle('repoPom${repository.id}','slide'); return false;">Show POM Snippet</a><br/>
- <%-- DO NOT REFORMAT THIS SECTION --%>
-<pre class="pom" style="display: none;" id="repoPom${repository.id}"><code><project>
- ...
- <distributionManagement>
- <${repository.includeSnapshots ? 'snapshotRepository' : 'repository'}>
- <id>${repository.id}</id>
- <url>dav:${urlbase}${repository.urlName}</url>
- <c:if test="${repository.layout != 'default'}">
- <layout>${repository.layout}</layout>
- </c:if>
- </${repository.includeSnapshots ? 'snapshotRepository' : 'repository'}>
- </distributionManagement>
-
- <repositories>
- <repository>
- <id>${repository.id}</id>
- <name>${repository.name}</name>
- <url>${urlbase}${repository.urlName}/</url>
- <c:if test="${repository.layout != 'default'}">
- <layout>${repository.layout}</layout>
- </c:if>
- <releases>
- <enabled>${repository.includeSnapshots ? 'false' : 'true'}</enabled>
- </releases>
- <snapshots>
- <enabled>${repository.includeSnapshots ? 'true' : 'false'}</enabled>
- </snapshots>
- </repository>
- </repositories>
- ...
- </project>
-</code></pre>
- </td>
- </tr>
- </table>
- </div>
-</c:forEach>
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
-
-<html>
-<head>
- <title>Administration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Administration</h1>
-
-<div id="contentArea">
- <div>
-
- <%-- TODO replace with icons --%>
- <div style="float: right">
- <pss:ifAuthorized permission="archiva-manage-configuration">
- <a href="<ww:url action="addProxiedRepository" method="input" />">Add Repository</a>
- </pss:ifAuthorized>
- </div>
-
- <h2>Proxied Repositories</h2>
- </div>
-
- <ww:set name="proxiedRepositories" value="proxiedRepositories"/>
- <c:if test="${empty(proxiedRepositories)}">
- <strong>There are no proxied repositories configured yet.</strong>
- </c:if>
- <c:forEach items="${proxiedRepositories}" var="repository" varStatus="i">
- <div>
- <div style="float: right">
- <%-- TODO replace with icons --%>
- <pss:ifAuthorized permission="archiva-manage-configuration">
- <a href="<ww:url action="editProxiedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Edit
- Repository</a> | <a
- href="<ww:url action="deleteProxiedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Delete
- Repository</a>
- </pss:ifAuthorized>
- </div>
- <h3>${repository.name}</h3>
- <table class="infoTable">
- <tr>
- <th>Identifier</th>
- <td>
- <code>${repository.id}</code>
- </td>
- </tr>
- <tr>
- <th>URL</th>
- <td><a href="${repository.url}">${repository.url}</a></td>
- </tr>
- <tr>
- <th>Type</th>
- <%-- TODO: can probably just use layout appended to a key prefix in i18n to simplify this --%>
- <td>
- <c:choose>
- <c:when test="${repository.layout == 'default'}">
- Maven 2.x Repository
- </c:when>
- <c:otherwise>
- Maven 1.x Repository
- </c:otherwise>
- </c:choose>
- </td>
- </tr>
- <tr>
- <th>Snapshots</th>
- <td>
- <my:displayUpdatePolicy policy="${repository.snapshotsPolicy}" interval="${repository.snapshotsInterval}"/>
- </td>
- </tr>
- <tr>
- <th>Releases</th>
- <td>
- <my:displayUpdatePolicy policy="${repository.releasesPolicy}" interval="${repository.releasesInterval}"/>
- </td>
- </tr>
- <tr>
- <th>Proxied through</th>
- <td>
- <%-- TODO: this is the hard way! would be nice if there was a ref in the model so it was directly linked --%>
- ${repositoriesMap[repository.managedRepository].name}
- (<code>${repositoriesMap[repository.managedRepository].id}</code>)
- </td>
- </tr>
- <tr>
- <th>Use HTTP Proxy</th>
- <td class="${repository.useNetworkProxy ? 'donemark' : 'errormark'} booleanIcon"></td>
- </tr>
- <tr>
- <th>Cache Failures</th>
- <td class="${repository.cacheFailures ? 'donemark' : 'errormark'} booleanIcon"></td>
- </tr>
- <tr>
- <th>Fail Whole Group</th>
- <td class="${repository.hardFail ? 'donemark' : 'errormark'} booleanIcon"></td>
- </tr>
- </table>
- </div>
- </c:forEach>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Configuration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Configuration</h1>
-
-<div id="contentArea">
-
- <h2>Add Synced Repository</h2>
-
- <ww:actionmessage/>
- <ww:form method="post" action="addSyncedRepository" namespace="/admin" validate="true">
- <ww:select list="#@java.util.LinkedHashMap@{
- 'rsync' : 'Rsync',
- 'svn' : 'Subversion',
- 'cvs' : 'CVS',
- 'file': 'Local File System'}" name="method" label="Method"/>
-
- <ww:submit value="Continue"/>
- </ww:form>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-<html>
-<head>
- <title>Administration</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Administration</h1>
-
-<div id="contentArea">
-<div>
- <%-- TODO replace with icons --%>
- <div style="float: right">
- <a href="<ww:url action="addSyncedRepository" method="input" />">Add Repository</a>
- </div>
- <h2>Synced Repositories</h2>
-</div>
-
-<ww:set name="syncedRepositories" value="syncedRepositories"/>
-<c:if test="${empty(syncedRepositories)}">
- <strong>There are no synced repositories configured yet.</strong>
-</c:if>
-<c:forEach items="${syncedRepositories}" var="repository" varStatus="i">
- <div>
- <div style="float: right">
- <%-- TODO replace with icons --%>
- <a href="<ww:url action="editSyncedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Edit
- Repository</a> | <a
- href="<ww:url action="deleteSyncedRepository" method="input"><ww:param name="repoId" value="%{'${repository.id}'}" /></ww:url>">Delete
- Repository</a>
- </div>
- <h3>${repository.name}</h3>
- <table class="infoTable">
- <tr>
- <th>Identifier</th>
- <td>
- <code>${repository.id}</code>
- </td>
- </tr>
- <tr>
- <th>Method</th>
- <td>${repository.method}</td>
- </tr>
- <c:choose>
- <c:when test="${repository.method == 'cvs'}">
- <tr>
- <th>CVS Root</th>
- <td>${repository.properties['cvsRoot']}</td>
- </tr>
- </c:when>
- <c:when test="${repository.method == 'svn'}">
- <tr>
- <th>Subversion URL</th>
- <td>${repository.properties['svnUrl']}</td>
- </tr>
- <tr>
- <th>Subversion Username</th>
- <td>${repository.properties['username']}</td>
- </tr>
- </c:when>
- <c:when test="${repository.method == 'rsync'}">
- <tr>
- <th>Rsync Host</th>
- <td>${repository.properties['rsyncHost']}</td>
- </tr>
- <tr>
- <th>Rsync Directory</th>
- <td>${repository.properties['rsyncDirectory']}</td>
- </tr>
- <tr>
- <th>Rsync Method</th>
- <td>
- <c:choose>
- <c:when test="${repository.properties['rsyncMethod'] == 'rsync'}">
- Anonymous
- </c:when>
- <c:when test="${repository.properties['rsyncMethod'] == 'ssh'}">
- SSH
- </c:when>
- </c:choose>
- </td>
- </tr>
- <tr>
- <th>Username</th>
- <td>${repository.properties['username']}</td>
- </tr>
- </c:when>
- <c:when test="${repository.method == 'file'}">
- <tr>
- <th>Directory</th>
- <td>${repository.properties['directory']}</td>
- </tr>
- </c:when>
- </c:choose>
- <tr>
- <th>Type</th>
- <%-- TODO: can probably just use layout appended to a key prefix in i18n to simplify this --%>
- <td>
- <c:choose>
- <c:when test="${repository.layout == 'default'}">
- Maven 2.x Repository
- </c:when>
- <c:otherwise>
- Maven 1.x Repository
- </c:otherwise>
- </c:choose>
- </td>
- </tr>
- <tr>
- <th>Synced to</th>
- <td>
- <%-- TODO: this is the hard way! would be nice if there was a ref in the model so it was directly linked --%>
- ${repositoriesMap[repository.managedRepository].name}
- (<code>${repositoriesMap[repository.managedRepository].id}</code>)
- </td>
- </tr>
- <tr>
- <th>Schedule</th>
- <td>${repository.cronExpression}</td>
- </tr>
- </table>
- </div>
-</c:forEach>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-<html>
-<head>
- <title>Security Alert Page</title>
- <ww:head/>
-</head>
-
-<body>
-
-<div id="contentArea">
- <div id="searchBox">
- <div id="results">
- You are not authorized for this activity.
- </div>
- </div>
-</div>
-
-<div class="clear">
- <hr/>
-</div>
-
-</body>
-
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
-
-<html>
-<head>
- <title>Browse Repository</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Browse Repository</h1>
-
-<div id="contentArea">
- <div id="nameColumn">
- <h2>Groups</h2>
- <ul>
- <ww:set name="groups" value="groups"/>
- <c:forEach items="${groups}" var="groupId">
- <c:set var="url">
- <ww:url action="browseGroup" namespace="/">
- <ww:param name="groupId" value="%{'${groupId}'}"/>
- </ww:url>
- </c:set>
- <li><a href="${url}">${groupId}/</a></li>
- </c:forEach>
- </ul>
- </div>
-
-
- <%-- TODO: later, when supported in metadata
- <div id="categoryColumn">
- <h2>Category</h2>
- <table>
- <tr>
- <td>
- <a href="#">Java</a>
- </td>
- </tr>
- <tr>
- <td>
- <a href="#">Ruby</a>
- </td>
- </tr>
- </table>
- </div>
-
- <h2>Labels</h2>
-
- <div id="labels">
- <p>
- <a href="#">jdo</a>
- <a href="#">j2ee</a>
- <a href="#">maven</a>
- </p>
- </div>
- --%>
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
-
-<html>
-<head>
- <title>Browse Repository</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Browse Repository</h1>
-
-<div id="contentArea">
- <div id="nameColumn">
- <p>
- <archiva:groupIdLink var="${groupId}" includeTop="true" />
- <strong>${artifactId}</strong>
- </p>
-
- <h2>Versions</h2>
- <ul>
- <ww:set name="versions" value="versions"/>
- <c:forEach items="${versions}" var="version">
- <c:set var="url">
- <ww:url action="showArtifact" namespace="/">
- <ww:param name="groupId" value="%{'${groupId}'}"/>
- <ww:param name="artifactId" value="%{'${artifactId}'}"/>
- <ww:param name="version" value="%{'${version}'}"/>
- </ww:url>
- </c:set>
- <li><a href="${url}">${version}/</a></li>
- </c:forEach>
- </ul>
- </div>
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
-
-<html>
-<head>
- <title>Browse Repository</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Browse Repository</h1>
-
-<div id="contentArea">
- <div id="nameColumn">
- <p>
- <archiva:groupIdLink var="${groupId}" includeTop="true" />
- </p>
-
- <ww:set name="groups" value="groups"/>
- <c:if test="${!empty(groups)}">
- <h2>Groups</h2>
- <ul>
- <c:forEach items="${groups}" var="groupId">
- <c:set var="url">
- <ww:url action="browseGroup" namespace="/">
- <ww:param name="groupId" value="%{'${groupId}'}"/>
- </ww:url>
- </c:set>
- <li><a href="${url}">${groupId}/</a></li>
- </c:forEach>
- </ul>
- </c:if>
-
- <ww:set name="artifactIds" value="artifactIds"/>
- <c:if test="${!empty(artifactIds)}">
- <h2>Artifacts</h2>
- <ul>
- <c:forEach items="${artifactIds}" var="artifactId">
- <c:set var="url">
- <ww:url action="browseArtifact" namespace="/">
- <ww:param name="groupId" value="%{'${groupId}'}"/>
- <ww:param name="artifactId" value="%{'${artifactId}'}"/>
- </ww:url>
- </c:set>
- <li><a href="${url}">${artifactId}/</a></li>
- </c:forEach>
- </ul>
- </c:if>
- </div>
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib uri="/webwork" prefix="ww" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<ww:set name="companyLogo" value="companyLogo"/>
-<c:if test="${!empty(companyLogo)}">
- <ww:set name="companyUrl" value="companyUrl"/>
- <c:choose>
- <c:when test="${!empty(companyUrl)}">
- <a href="${companyUrl}">
- <img src="${companyLogo}" title="${companyName}" border="0" alt=""/>
- </a>
- </c:when>
- <c:otherwise>
- <img src="${companyLogo}" title="${companyName}" border="0" alt=""/>
- </c:otherwise>
- </c:choose>
-</c:if>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
-<%@ taglib uri="/webwork" prefix="ww" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
-<%@ page import="java.util.Calendar" %>
-<html>
-<head>
- <title>Maven Archiva ::
- <decorator:title default="Maven Archiva"/>
- </title>
-
- <style type="text/css" media="all">
- @import url( "<c:url value="/css/maven-base.css" />" );
- @import url( "<c:url value="/css/maven-theme.css" />" );
- @import url( "<c:url value="/css/pss/table.css" />" );
- @import url( "<c:url value="/css/site.css" />" );
- </style>
- <link rel="stylesheet" href="<c:url value="/css/print.css"/>" type="text/css" media="print"/>
- <script type="text/javascript" src="<c:url value="/js/scriptaculous/prototype.js"/>"></script>
- <script type="text/javascript" src="<c:url value="/js/scriptaculous/scriptaculous.js"/>"></script>
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
-</head>
-
-<body onload="<decorator:getProperty property="body.onload" />" class="composite">
-<div id="banner">
- <span id="bannerLeft">
- <a href="http://maven.apache.org/archiva/">
- <img src="<c:url value='/images/archiva.png' />" alt="" width="188" height="69"/>
- </a>
- </span>
- <span id="bannerRight">
- <ww:action namespace="/components" name="companyInfo" executeResult="true"/>
- </span>
-
- <div class="clear">
- <hr/>
- </div>
-</div>
-
-<div id="breadcrumbs">
- <div class="xleft">
- <%@ include file="/WEB-INF/jsp/pss/include/securityLinks.jsp" %>
- </div>
-
- <div class="xright">
- <a href="http://maven.apache.org/archiva">Archiva</a> |
- <a href="http://maven.apache.org/">Maven</a> |
- <a href="http://www.apache.org/">Apache</a>
- </div>
-
- <div class="clear">
- <hr/>
- </div>
-</div>
-
-<div id="leftColumn">
-
- <div id="navcolumn">
-
- <h5>Find</h5>
- <ul>
- <li class="none">
- <my:currentWWUrl action="index" namespace="/">Search</my:currentWWUrl>
- </li>
-
- <li class="none">
- <my:currentWWUrl action="findArtifact" namespace="/">Find Artifact</my:currentWWUrl>
- </li>
-
- <li class="none">
- <my:currentWWUrl action="browse" namespace="/">Browse</my:currentWWUrl>
- </li>
- </ul>
-
- <pss:ifAnyAuthorized permissions="archiva-manage-users,archiva-access-reports,archiva-manage-configuration">
- <h5>Manage</h5>
- <ul>
- <pss:ifAuthorized permission="archiva-access-reports">
- <li class="none">
- <my:currentWWUrl action="reports" namespace="/admin">Reports</my:currentWWUrl>
- </li>
- </pss:ifAuthorized>
- <%-- TODO
- <li class="none">
- <a href="#">Synchronisation</a>
- </li>
- --%>
- <pss:ifAuthorized permission="archiva-manage-users">
- <li class="none">
- <my:currentWWUrl action="userlist" namespace="/security">User Management</my:currentWWUrl>
- </li>
- </pss:ifAuthorized>
- <pss:ifAuthorized permission="archiva-manage-configuration">
- <li class="none">
- <my:currentWWUrl action="configureAppearance" namespace="/admin">Appearance</my:currentWWUrl>
- </li>
- </pss:ifAuthorized>
- </ul>
- </pss:ifAnyAuthorized>
-
- <pss:ifAuthorized permission="archiva-manage-configuration">
- <h5>Administration</h5>
- <ul>
- <li class="none">
- <my:currentWWUrl action="index" namespace="/admin">Settings</my:currentWWUrl>
- </li>
- <li class="none">
- <my:currentWWUrl action="managedRepositories" namespace="/admin">Managed Repositories</my:currentWWUrl>
- </li>
- <li class="none">
- <my:currentWWUrl action="proxiedRepositories" namespace="/admin">Proxied Repositories</my:currentWWUrl>
- </li>
-
- <%-- TODO: add back after synced repos are implemented
- <li class="none">
- <my:currentWWUrl action="syncedRepositories" namespace="/admin">Synced Repositories</my:currentWWUrl>
- </li>
- --%>
- </ul>
- </pss:ifAuthorized>
-
- </div>
-</div>
-
-<div id="bodyColumn">
- <div id="contentBox">
- <decorator:body/>
- </div>
-</div>
-
-<div class="clear">
- <hr/>
-</div>
-
-<%
- int inceptionYear = 2005;
- int currentYear = Calendar.getInstance().get( Calendar.YEAR );
- String copyrightRange = String.valueOf( inceptionYear );
- if ( inceptionYear != currentYear )
- {
- copyrightRange = copyrightRange + "-" + String.valueOf( currentYear );
- }
-%>
-<div id="footer">
- <div class="xright">©
- Copyright © <%= copyrightRange %> Apache Software Foundation
- </div>
-
- <div class="clear">
- <hr/>
-
- </div>
-</div>
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<html>
-<head>
- <title>Find Artifact</title>
- <ww:head/>
-</head>
-
-<body onload="document.checksumSearch.file.disabled = false">
-
-<h1>Find Artifact</h1>
-
-<div id="contentArea">
- <div id="searchBox">
- <script type="text/javascript">
- function generateMd5( file, defVal )
- {
- if ( file )
- {
- var s = document.ChecksumApplet.generateMd5(file);
- // If there is a space, it's an error message, not a checksum
- if ( s.indexOf(" ") >= 0 )
- {
- alert(s);
- return "";
- }
- else
- return s;
- }
- return defVal;
- }
- </script>
-
- <noscript>
- <span class="errorMessage">JavaScript is disabled: using the file browser will not work.</span>
- </noscript>
-
- <ww:form method="POST" action="checksumSearch" namespace="/"
- onsubmit="this.md5.value = generateMd5(this.file.value,this.md5.value); this.file.disabled = true">
- <tr>
- <td class="tdLabel"><label for="checksumSearch_file" class="label">Search for:</label></td>
- <td>
- <input type="file" name="file" size="50" value="" id="checksumSearch_file"/>
- </td>
- </tr>
- <ww:textfield label="Checksum" size="50" name="md5"/>
- <ww:submit value="Go!"/>
- </ww:form>
-
- <p>
- Select the file you would like to locate in the remote repository.
- The entire file will
- <b>not</b>
- be uploaded to the server. See the progress bar below for progress of
- locally creating a checksum that is uploaded to the server after you hit "Go!".
- <ww:actionerror/>
- </p>
-
- <p>
- <applet code="org/apache/maven/archiva/applet/ChecksumApplet.class"
- archive="archiva-applet.jar"
- width="400" height="20" name="ChecksumApplet">
- </applet>
- </p>
-
- </div>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-<html>
-<head>
- <title>Error Occurred</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Error Occurred</h1>
-
-<ww:actionerror/>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-
-<%-- TODO: paginate! --%>
-<c:forEach items="${dependencies}" var="dependency">
- <h3 class="artifact-title">
- <my:showArtifactTitle groupId="${dependency.groupId}" artifactId="${dependency.artifactId}"
- version="${dependency.version}"/>
-
- </h3>
-
- <p>
- <my:showArtifactLink groupId="${dependency.groupId}" artifactId="${dependency.artifactId}"
- version="${dependency.version}" versions="${dependency.versions}" scope="${dependency.scope}"
- classifier="${dependency.classifier}"/>
- </p>
-</c:forEach>
-<c:if test="${empty(dependencies)}">
- <strong>No results</strong>
-</c:if>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
-
-<p>
- <archiva:groupIdLink var="${model.groupId}" includeTop="true" />
-
- <c:set var="url">
- <ww:url action="browseArtifact" namespace="/">
- <ww:param name="groupId" value="%{'${model.groupId}'}"/>
- <ww:param name="artifactId" value="%{'${model.artifactId}'}"/>
- </ww:url>
- </c:set>
- <a href="${url}">${model.artifactId}</a> /
- <strong>${model.version}</strong>
-
- <%-- TODO: new versions?
- (<strong class="statusFailed">Newer version available:</strong>
- <a href="artifact.html">2.0.3</a>)
- --%>
-</p>
-
-<c:if test="${!empty(model.description)}">
- <blockquote>${model.description}</blockquote>
-</c:if>
-
-<table class="infoTable">
- <tr>
- <th>Group ID</th>
- <td>${model.groupId}</td>
- </tr>
- <tr>
- <th>Artifact ID</th>
- <td>${model.artifactId}</td>
- </tr>
- <tr>
- <th>Version</th>
- <td>${model.version}</td>
- </tr>
- <tr>
- <th>Packaging</th>
- <td><code>${model.packaging}</code></td>
- </tr>
- <%-- TODO: derivatives
- <tr>
- <th>Derivatives</th>
- <td>
- <a href="#">Source</a>
- |
- <a href="#">Javadoc</a>
- </td>
- </tr>
- --%>
- <c:if test="${model.parent != null}">
- <tr>
- <th>Parent</th>
- <td>
- ${model.parent.groupId} ${model.parent.artifactId} ${model.parent.version}
- <c:set var="url">
- <ww:url action="showArtifact" namespace="/">
- <ww:param name="groupId" value="%{'${model.parent.groupId}'}"/>
- <ww:param name="artifactId" value="%{'${model.parent.artifactId}'}"/>
- <ww:param name="version" value="%{'${model.parent.version}'}"/>
- </ww:url>
- </c:set>
- (<a href="${url}">View</a>)
- </td>
- </tr>
- </c:if>
- <%-- TODO: deployment timestamp
- <tr>
- <th>Deployment Date</th>
- <td>
- 15 Jan 2006, 20:38:00 +1000
- </td>
- </tr>
- --%>
- <%-- TODO: origin
- <tr>
- <th>Origin</th>
- <td>
- <a href="TODO">Apache Repository</a>
- </td>
- </tr>
- --%>
-</table>
-
-<c:if test="${model.packaging != 'pom'}">
- <h2>POM Dependency Snippet</h2>
-<pre class="pom">
- <dependency>
- <groupId>${model.groupId}</groupId>
- <artifactId>${model.artifactId}</artifactId>
- <version>${model.version}</version><c:if test="${model.packaging != 'jar'}">
- <type>${model.packaging}</type></c:if>
- </dependency>
-</pre>
-</c:if>
-
-<c:if test="${!empty(model.url) || model.organization != null || !empty(model.licenses)
- || model.issueManagement != null || model.ciManagement != null}">
-
- <h2>Other Details</h2>
- <table class="infoTable">
- <c:if test="${!empty(model.url)}">
- <tr>
- <th>URL</th>
- <td>
- <a href="${model.url}">${model.url}</a>
- </td>
- </tr>
- </c:if>
- <c:if test="${model.organization != null}">
- <tr>
- <th>Organisation</th>
- <td>
- <c:choose>
- <c:when test="${model.organization != null}">
- <a href="${model.organization.url}">${model.organization.name}</a>
- </c:when>
- <c:otherwise>
- ${model.organization.name}
- </c:otherwise>
- </c:choose>
- </td>
- </tr>
- </c:if>
- <c:if test="${!empty(model.licenses)}">
- <c:forEach items="${model.licenses}" var="license">
- <tr>
- <th>License</th>
- <td>
- <c:choose>
- <c:when test="${!empty(license.url)}">
- <a href="${license.url}">${license.name}</a>
- </c:when>
- <c:otherwise>
- ${license.name}
- </c:otherwise>
- </c:choose>
- </td>
- </tr>
- </c:forEach>
- </c:if>
- <c:if test="${model.issueManagement != null}">
- <tr>
- <th>Issue Tracker</th>
- <td>
- <c:choose>
- <c:when test="${!empty(model.issueManagement.url)}">
- <a href="${model.issueManagement.url}">${model.issueManagement.system}</a>
- </c:when>
- <c:otherwise>
- ${model.issueManagement.system}
- </c:otherwise>
- </c:choose>
- </td>
- </tr>
- </c:if>
- <c:if test="${model.ciManagement != null}">
- <tr>
- <th>Continuous Integration</th>
- <td>
- <c:choose>
- <c:when test="${!empty(model.ciManagement.url)}">
- <a href="${model.ciManagement.url}">${model.ciManagement.system}</a>
- </c:when>
- <c:otherwise>
- ${model.ciManagement.system}
- </c:otherwise>
- </c:choose>
- </td>
- </tr>
- </c:if>
- </table>
-</c:if>
-
-<c:if test="${model.scm != null}">
- <h2>SCM</h2>
- <table class="infoTable">
- <c:if test="${!empty(model.scm.connection)}">
- <tr>
- <th>Connection</th>
- <td>
- <code>${model.scm.connection}</code>
- </td>
- </tr>
- </c:if>
- <c:if test="${!empty(model.scm.developerConnection)}">
- <tr>
- <th>Dev. Connection</th>
- <td>
- <code>${model.scm.developerConnection}</code>
- </td>
- </tr>
- </c:if>
- <c:if test="${!empty(model.scm.url)}">
- <tr>
- <th>Viewer</th>
- <td>
- <a href="${model.scm.url}">${model.scm.url}</a>
- </td>
- </tr>
- </c:if>
- </table>
-</c:if>
-
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-
-<c:forEach items="${reports}" var="report">
- <h3>
- ${report.groupId} : ${report.artifactId} : ${report.version} : ${report.classifier} : ${report.type}
- </h3>
- <ul>
- <c:forEach items="${repor.results}" var="result">
- <li>
- <b>${result.reason}</b>
- </li>
- </c:forEach>
- </ul>
-</c:forEach>
-<c:if test="${empty(reports)}">
- <strong>No reports for this artifact.</strong>
-</c:if>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-
-<ul class="dependencyTree">
-<c:set var="prevDepth" value="1"/>
-<ww:set name="dependencyTree" value="dependencyTree"/>
-<c:forEach items="${dependencyTree}" var="node">
- <c:choose>
- <c:when test="${node.depth < prevDepth}">
- </ul>
- <li>
- </c:when>
- <c:when test="${node.depth > prevDepth}">
- <ul>
- <li>
- </c:when>
- <c:otherwise>
- <li>
- </c:otherwise>
- </c:choose>
- <my:showArtifactLink groupId="${node.artifact.groupId}" artifactId="${node.artifact.artifactId}"
- version="${node.artifact.version}"/>
- </li>
- <c:set var="prevDepth" value="${node.depth}"/>
-</c:forEach>
-</ul>
-
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-
-<c:forEach items="${mailingLists}" var="mailingList">
- <h3>
- ${mailingList.name}
- </h3>
- <%-- TODO: description
- <p>
- Description blah blah blah
- </p>
- --%>
- <ul>
- <c:if test="${!empty(mailingList.subscribe)}">
- <li>
- <b>Subscribe:</b>
- <a href="mailto:${mailingList.subscribe}">${mailingList.subscribe}</a>
- </li>
- </c:if>
- <c:if test="${!empty(mailingList.post)}">
- <li>
- <b>Post:</b>
- <a href="mailto:${mailingList.post}">${mailingList.post}</a>
- </li>
- </c:if>
- <c:if test="${!empty(mailingList.unsubscribe)}">
- <li>
- <b>Unsubscribe:</b>
- <a href="mailto:${mailingList.unsubscribe}">${mailingList.unsubscribe}</a>
- </li>
- </c:if>
- <%-- TODO: not in the POM yet
- <li>
- <b>List owner:</b>
- <a href="mailto:${mailingList.owner}">${mailingList.owner}</a>
- </li>
- --%>
- <c:if test="${!empty(mailingList.archive)}">
- <li>
- <b>Archive:</b>
- <ul>
- <li>
- <a href="${mailingList.archive}">${mailingList.archive}</a>
- </li>
- </ul>
- </li>
- </c:if>
- <c:if test="${!empty(mailingList.otherArchives)}">
- <li>
- <b>Other Archives:</b>
- <ul>
- <c:forEach items="${mailingList.otherArchives}" var="archive">
- <li>
- <a href="${archive}">${archive}</a>
- </li>
- </c:forEach>
- </ul>
- </li>
- </c:if>
- </ul>
-</c:forEach>
-<c:if test="${empty(mailingLists)}">
- <strong>No mailing lists</strong>
-</c:if>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-
-<div id="searchBox">
- <ww:form method="get" action="quickSearch" validate="true">
- <ww:textfield label="Search for" size="50" name="q"/>
- <ww:submit label="Go!"/>
- </ww:form>
-
- <script type="text/javascript">
- document.getElementById("quickSearch_q").focus();
- </script>
-
- <p>
- Enter your search terms. A variety of data will be searched for your keywords.
- <ww:actionerror/>
- </p>
-</div>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<html>
-<head>
- <title>Quick Search</title>
- <ww:head/>
-</head>
-
-<ww:if test="%{infoMessage != null}">
- <p>${infoMessage}</p>
-</ww:if>
-
-<body>
-
-<h1>Search</h1>
-
-<div id="contentArea">
- <%@ include file="/WEB-INF/jsp/include/quickSearchForm.jspf" %>
-</div>
-
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
-<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
-<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-
-<html>
-<head>
- <title>Reports</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Reports</h1>
-
-<div id="contentArea">
-
-<c:forEach items="${reports}" var="report">
- <h3>
- ${report.groupId} : ${report.artifactId} : ${report.version} : ${report.classifier} : ${report.type}
- </h3>
- <ul>
- <c:forEach items="${repor.results}" var="result">
- <li>
- <b>${result.reason}</b>
- </li>
- </c:forEach>
- </ul>
-</c:forEach>
-<c:if test="${empty(reports)}">
- <strong>No reports for any artifact.</strong>
-</c:if>
-
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib uri="/webwork" prefix="ww" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-
-<html>
-<head>
- <title>Search Results</title>
- <ww:head/>
-</head>
-
-<body>
-
-<h1>Search</h1>
-
-<div id="contentArea">
- <div id="searchBox">
- <%@ include file="/WEB-INF/jsp/include/quickSearchForm.jspf" %>
- </div>
-
- <h1>Results</h1>
-
- <div id="resultsBox">
- <ww:set name="searchResults" value="searchResults"/>
- <c:forEach items="${searchResults}" var="record" varStatus="i">
-
-
- <h3 class="artifact-title">
- <my:showArtifactTitle groupId="${record.groupId}" artifactId="${record.artifactId}"
- version="${record.version}"/>
- </h3>
-
- <p>
- <my:showArtifactLink groupId="${record.groupId}" artifactId="${record.artifactId}"
- version="${record.version}" versions="${record.versions}"/>
-
- <%-- TODO: hits
- <table border="1px" width="100%" cellspacing="0">
- <c:forEach items="${result.fieldMatchesEntrySet}" var="entry">
- <tr>
- <td valign="top" width="15%" align="right"><c:out value="${entry.key}"/></td>
- <td valign="top">
- <c:forEach items="${entry.value}" var="item">
- <c:out value="${item}" />
- </c:forEach>
- <br/>
- </td>
- </tr>
- </c:forEach>
- </table>
- </td>
- <td>
-
- <code>org.apache.maven</code>
- (package)
- <br/>
- <code>org.apache.maven.model</code>
- (package)
- </td>
- <td>
- <a href="artifact.html">Details</a>
- </td>
- --%>
- </p>
- </c:forEach>
- </div>
-</div>
-</body>
-</html>
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
-<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
-<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
-
-<html>
-<head>
- <title>Browse Repository</title>
- <ww:head/>
-</head>
-
-<body>
-
-<ww:set name="model" value="model"/>
-<c:choose>
- <c:when test="${model.packaging == 'maven-plugin'}">
- <c:url var="imageUrl" value="/images/mavenplugin.gif"/>
- <c:set var="packageName">Maven Plugin</c:set>
- </c:when>
- <c:when test="${model.packaging == 'pom'}">
- <c:url var="imageUrl" value="/images/pom.gif"/>
- <c:set var="packageName">POM</c:set>
- </c:when>
- <%-- These types aren't usually set in the POM yet, so we fudge them for the well known ones --%>
- <c:when test="${model.packaging == 'maven-archetype' or model.groupId == 'org.apache.maven.archetypes'}">
- <c:url var="imageUrl" value="/images/archetype.gif"/>
- <c:set var="packageName">Maven Archetype</c:set>
- </c:when>
- <c:when test="${model.packaging == 'maven-skin' or model.groupId == 'org.apache.maven.skins'}">
- <c:url var="imageUrl" value="/images/skin.gif"/>
- <c:set var="packageName">Maven Skin</c:set>
- </c:when>
- <%-- Must be last so that the above get picked up if possible --%>
- <c:when test="${model.packaging == 'jar'}">
- <c:url var="imageUrl" value="/images/jar.gif"/>
- <c:set var="packageName">JAR</c:set>
- </c:when>
- <c:otherwise>
- <c:url var="imageUrl" value="/images/other.gif"/>
- <c:set var="packageName"></c:set>
- </c:otherwise>
-</c:choose>
-<img src="${imageUrl}" width="66" height="66" alt="${packageName}" title="${packageName}" style="float: left"/>
-
-<h1>
- <c:choose>
- <c:when test="${empty(model.name)}">
- ${model.artifactId}
- </c:when>
- <c:otherwise>
- ${model.name}
- </c:otherwise>
- </c:choose>
-</h1>
-
-<div id="contentArea">
- <div id="tabs">
- <span>
- <c:set var="url">
- <ww:url action="showArtifact">
- <ww:param name="groupId" value="%{groupId}"/>
- <ww:param name="artifactId" value="%{artifactId}"/>
- <ww:param name="version" value="%{version}"/>
- </ww:url>
- </c:set>
- <my:currentWWUrl url="${url}">Info</my:currentWWUrl>
- <c:set var="url">
- <ww:url action="showArtifactDependencies">
- <ww:param name="groupId" value="%{groupId}"/>
- <ww:param name="artifactId" value="%{artifactId}"/>
- <ww:param name="version" value="%{version}"/>
- </ww:url>
- </c:set>
- <my:currentWWUrl url="${url}">Dependencies</my:currentWWUrl>
- <c:set var="url">
- <ww:url action="showArtifactDependencyTree">
- <ww:param name="groupId" value="%{groupId}"/>
- <ww:param name="artifactId" value="%{artifactId}"/>
- <ww:param name="version" value="%{version}"/>
- </ww:url>
- </c:set>
- <my:currentWWUrl url="${url}">Dependency Tree</my:currentWWUrl>
- <c:set var="url">
- <ww:url action="showArtifactDependees">
- <ww:param name="groupId" value="%{groupId}"/>
- <ww:param name="artifactId" value="%{artifactId}"/>
- <ww:param name="version" value="%{version}"/>
- </ww:url>
- </c:set>
- <my:currentWWUrl url="${url}">Used By</my:currentWWUrl>
- <c:set var="url">
- <ww:url action="showArtifactMailingLists">
- <ww:param name="groupId" value="%{groupId}"/>
- <ww:param name="artifactId" value="%{artifactId}"/>
- <ww:param name="version" value="%{version}"/>
- </ww:url>
- </c:set>
- <my:currentWWUrl url="${url}">Mailing Lists</my:currentWWUrl>
- <pss:ifAnyAuthorized permissions="archiva-access-reports">
- <c:set var="url">
- <ww:url action="showArtifactReports">
- <ww:param name="groupId" value="%{groupId}"/>
- <ww:param name="artifactId" value="%{artifactId}"/>
- <ww:param name="version" value="%{version}"/>
- </ww:url>
- </c:set>
- <my:currentWWUrl url="${url}">Reports</my:currentWWUrl>
- </pss:ifAnyAuthorized>
-
- </span>
- </div>
-
-<div class="sidebar3">
- <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${Version}" />
-</div>
-
- <%-- TODO: perhaps using ajax? --%>
- <%-- TODO: panels? this is ugly as is! --%>
- <div id="tabArea">
- <c:choose>
- <c:when test="${dependencies != null}">
- <%@ include file="/WEB-INF/jsp/include/artifactDependencies.jspf" %>
- </c:when>
- <c:when test="${dependencyTree != null}">
- <%@ include file="/WEB-INF/jsp/include/dependencyTree.jspf" %>
- </c:when>
- <c:when test="${mailingLists != null}">
- <%@ include file="/WEB-INF/jsp/include/mailingLists.jspf" %>
- </c:when>
- <c:when test="${reports != null}">
- <%@ include file="/WEB-INF/jsp/include/artifactReports.jspf" %>
- </c:when>
- <c:otherwise>
- <%@ include file="/WEB-INF/jsp/include/artifactInfo.jspf" %>
- </c:otherwise>
- </c:choose>
- </div>
-</div>
-
-</body>
-</html>
+++ /dev/null
-<%--\r
- ~ Licensed to the Apache Software Foundation (ASF) under one\r
- ~ or more contributor license agreements. See the NOTICE file\r
- ~ distributed with this work for additional information\r
- ~ regarding copyright ownership. The ASF licenses this file\r
- ~ to you under the Apache License, Version 2.0 (the\r
- ~ "License"); you may not use this file except in compliance\r
- ~ with the License. You may obtain a copy of the License at\r
- ~\r
- ~ http://www.apache.org/licenses/LICENSE-2.0\r
- ~\r
- ~ Unless required by applicable law or agreed to in writing,\r
- ~ software distributed under the License is distributed on an\r
- ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r
- ~ KIND, either express or implied. See the License for the\r
- ~ specific language governing permissions and limitations\r
- ~ under the License.\r
- --%>\r
-\r
-<%@ taglib uri="/webwork" prefix="ww" %>\r
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\r
-<%@ attribute name="action" %>\r
-<%@ attribute name="namespace" %>\r
-<%@ attribute name="url" %>\r
-\r
-<c:set var="currentUrl">\r
- <ww:url/>\r
-</c:set>\r
-<c:if test="${!empty(action) && !empty(namespace)}">\r
- <c:set var="url">\r
- <ww:url action="${action}" namespace="${namespace}"/>\r
- </c:set>\r
-</c:if>\r
-<c:set var="text">\r
- <jsp:doBody/>\r
-</c:set>\r
-<c:choose>\r
- <c:when test="${currentUrl == url}">\r
- <b>${text}</b>\r
- </c:when>\r
- <c:otherwise>\r
- <a href="${url}">${text}</a>\r
- </c:otherwise>\r
-</c:choose>\r
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%-- TODO: this could perhaps just be a i18n call --%>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ attribute name="policy" required="true" %>
-<%@ attribute name="interval" %>
-
-<c:choose>
- <c:when test="${policy == 'disabled'}">
- Disabled
- </c:when>
- <c:when test="${policy == 'always'}">
- Updated every request
- </c:when>
- <c:when test="${policy == 'hourly'}">
- Updated hourly
- </c:when>
- <c:when test="${policy == 'daily'}">
- Updated daily
- </c:when>
- <c:when test="${policy == 'interval'}">
- Updated every ${interval} minutes
- </c:when>
-</c:choose>
\ No newline at end of file
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%@ taglib prefix="ww" uri="/webwork" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
-<%@ attribute name="groupId" required="true" %>
-<%@ attribute name="artifactId" %>
-<%@ attribute name="version" %>
-<%@ attribute name="classifier" %>
-<%@ attribute name="scope" %>
-<%@ attribute name="versions" type="java.util.List" %>
-
-<span class="artifact-link">
- <archiva:groupIdLink var="${model.groupId}" includeTop="true" />
-
- <c:if test="${!empty(artifactId)}">
- <c:set var="url">
- <ww:url action="browseArtifact" namespace="/">
- <ww:param name="groupId" value="%{'${groupId}'}"/>
- <ww:param name="artifactId" value="%{'${artifactId}'}"/>
- </ww:url>
- </c:set>
- / <a href="${url}">${artifactId}</a>
- </c:if>
- | <strong>Version(s):</strong>
- <c:choose>
- <c:when test="${!empty(version)}">
- <c:set var="url">
- <ww:url action="showArtifact" namespace="/">
- <ww:param name="groupId" value="%{'${groupId}'}"/>
- <ww:param name="artifactId" value="%{'${artifactId}'}"/>
- <c:if test="${!empty(version)}">
- <ww:param name="version" value="%{'${version}'}"/>
- </c:if>
- </ww:url>
- </c:set>
- <a href="${url}">${version}</a>
- </c:when>
- <c:otherwise>
- <c:forEach items="${versions}" var="v" varStatus="i">
- <c:set var="url">
- <ww:url action="showArtifact" namespace="/">
- <ww:param name="groupId" value="%{'${groupId}'}"/>
- <ww:param name="artifactId" value="%{'${artifactId}'}"/>
- <ww:param name="version" value="%{'${v}'}"/>
- </ww:url>
- </c:set>
- <a href="${url}">${v}</a>
- <c:if test="${!i.last}">,</c:if>
- </c:forEach>
- </c:otherwise>
- </c:choose>
- <c:if test="${!empty(scope)}">
- | <strong>Scope:</strong> ${scope}
- </c:if>
- <c:if test="${!empty(classifier)}">
- | <strong>Classifier:</strong> ${classifier}
- </c:if>
-</span>
+++ /dev/null
-<%--\r
- ~ Licensed to the Apache Software Foundation (ASF) under one\r
- ~ or more contributor license agreements. See the NOTICE file\r
- ~ distributed with this work for additional information\r
- ~ regarding copyright ownership. The ASF licenses this file\r
- ~ to you under the Apache License, Version 2.0 (the\r
- ~ "License"); you may not use this file except in compliance\r
- ~ with the License. You may obtain a copy of the License at\r
- ~\r
- ~ http://www.apache.org/licenses/LICENSE-2.0\r
- ~\r
- ~ Unless required by applicable law or agreed to in writing,\r
- ~ software distributed under the License is distributed on an\r
- ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r
- ~ KIND, either express or implied. See the License for the\r
- ~ specific language governing permissions and limitations\r
- ~ under the License.\r
- --%>\r
-\r
-<%@ taglib prefix="ww" uri="/webwork" %>\r
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\r
-<%@ attribute name="groupId" required="true" %>\r
-<%@ attribute name="artifactId" %>\r
-<%@ attribute name="version" %>\r
-\r
- <span class="artifact-title">\r
- <c:set var="url">\r
- <c:choose>\r
- <c:when test="${!empty(version)}">\r
- <ww:url action="showArtifact" namespace="/">\r
- <ww:param name="groupId" value="%{'${groupId}'}"/>\r
- <ww:param name="artifactId" value="%{'${artifactId}'}"/>\r
- <ww:param name="version" value="%{'${version}'}"/>\r
- </ww:url>\r
- </c:when>\r
- <c:otherwise>\r
- <ww:url action="browseArtifact" namespace="/">\r
- <ww:param name="groupId" value="%{'${groupId}'}"/>\r
- <ww:param name="artifactId" value="%{'${artifactId}'}"/>\r
- </ww:url>\r
- </c:otherwise>\r
- </c:choose>\r
- </c:set>\r
- <%-- TODO: showing the name and description would be nice, but that would require loading the POMs --%>\r
- <a href="${url}">${artifactId}</a>\r
- </span>\r
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
-
- <display-name>Maven Archiva</display-name>
-
- <filter>
- <filter-name>webwork-cleanup</filter-name>
- <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>
- </filter>
-
- <filter>
- <filter-name>sitemesh</filter-name>
- <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
- </filter>
-
- <filter>
- <filter-name>webwork</filter-name>
- <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
- </filter>
-
- <!-- this must be before the sitemesh filter -->
- <filter-mapping>
- <filter-name>webwork-cleanup</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <filter-mapping>
- <filter-name>sitemesh</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <filter-mapping>
- <filter-name>webwork</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <listener>
- <listener-class>org.codehaus.plexus.xwork.PlexusLifecycleListener</listener-class>
- </listener>
-
- <servlet>
- <servlet-name>RepositoryServlet</servlet-name>
- <servlet-class>org.apache.maven.archiva.web.repository.RepositoryServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>RepositoryServlet</servlet-name>
- <url-pattern>/repository/*</url-pattern>
- </servlet-mapping>
-
-</web-app>
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-body {
- margin: 0px;
- padding: 0px;
-}
-
-img {
- border: none;
-}
-
-table {
- padding: 0px;
- width: 100%;
- margin-left: -2px;
- margin-right: -2px;
-}
-
-acronym {
- cursor: help;
- border-bottom: 1px dotted #feb;
-}
-
-table.bodyTable th, table.bodyTable td {
- padding: 2px 4px 2px 4px;
- vertical-align: top;
-}
-
-div.clear {
- clear: both;
- visibility: hidden;
-}
-
-div.clear hr {
- display: none;
-}
-
-#bannerLeft, #bannerRight {
- font-size: xx-large;
- font-weight: bold;
-}
-
-#bannerLeft img, #bannerRight img {
- margin: 0px;
-}
-
-.xleft, #bannerLeft img {
- float: left;
- text-shadow: #7CFC00;
-}
-
-.xright, #bannerRight img {
- float: right;
- text-shadow: #7CFC00;
-}
-
-#banner {
- padding: 0px;
-}
-
-#banner img {
- border: none;
-}
-
-#breadcrumbs {
- padding: 3px 10px 3px 10px;
-}
-
-#leftColumn {
- height: 315px;
- width: 170px;
- float: left;
- overflow: auto;
-}
-
-#bodyColumn {
- margin-right: 1.5em;
- margin-left: 197px;
-}
-
-#legend {
- padding: 8px 0 8px 0;
-}
-
-#navcolumn {
- padding: 8px 4px 0 8px;
-}
-
-#navcolumn h5 {
- margin: 0;
- padding: 0;
- font-size: small;
-}
-
-#navcolumn ul {
- margin: 0;
- padding: 0;
- font-size: small;
-}
-
-#navcolumn li {
- list-style-type: none;
- background-image: none;
- background-repeat: no-repeat;
- background-position: 0 0.4em;
- padding-left: 16px;
- list-style-position: outside;
- line-height: 1.2em;
- font-size: smaller;
-}
-
-#navcolumn li.expanded {
- background-image: url( ../images/expanded.gif );
-}
-
-#navcolumn li.collapsed {
- background-image: url( ../images/collapsed.gif );
-}
-
-#poweredBy {
- text-align: center;
-}
-
-#navcolumn img {
- margin-top: 10px;
- margin-bottom: 3px;
-}
-
-#poweredBy img {
- display: block;
- margin: 20px 0 20px 17px;
- border: 1px solid black;
- width: 90px;
- height: 30px;
-}
-
-#search img {
- margin: 0px;
- display: block;
-}
-
-#search #q, #search #btnG {
- border: 1px solid #999;
- margin-bottom: 10px;
-}
-
-#search form {
- margin: 0px;
-}
-
-#lastPublished {
- font-size: x-small;
-}
-
-.navSection {
- margin-bottom: 2px;
- padding: 8px;
-}
-
-.navSectionHead {
- font-weight: bold;
- font-size: x-small;
-}
-
-.section {
- padding: 4px;
-}
-
-#footer {
- padding: 3px 10px 3px 10px;
- font-size: x-small;
-}
-
-#breadcrumbs {
- font-size: x-small;
- margin: 0pt;
-}
-
-.source {
- padding: 12px;
- margin: 1em 7px 1em 7px;
-}
-
-.source pre {
- margin: 0px;
- padding: 0px;
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-body {
- padding: 0 0 10px 0;
-}
-
-body, td, th, select, input, li {
- font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 13px;
-}
-
-select, input {
- font-size: x-small;
-}
-
-th {
- text-align: right;
- padding-right: 1em;
- font-size: x-small;
- vertical-align: top;
-}
-
-.infoTable th {
- width: 15em;
-}
-
-#contentBox h1 {
- background-image: url( ../images/arrow.gif );
- background-repeat: no-repeat;
- background-position: left bottom;
- border-bottom: 1px solid #DFDEDE;
- padding: 0 0 1px 23px;
- margin-bottom: 0.5em;
- color: #333;
- voice-family: inherit;
- font-size: medium !important;
-}
-
-#contentBox h2 {
- border-bottom: 1px solid #DFDEDE;
- padding: 0 0 1px 0;
- margin-bottom: 0.5em;
- color: #333;
- voice-family: inherit;
- font-size: small !important;
-}
-
-#contentBox h3 {
- border-bottom: 1px solid #DFDEDE;
- padding: 0 0 1px 0;
- margin-bottom: 0.5em;
- color: #333;
- voice-family: inherit;
- font-size: small !important;
- margin-left: 2em;
-}
-
-table {
- width: auto;
-}
-
-code {
- font-family: Courier, monospace;
- font-size: 13px;
-}
-
-#legend li.externalLink {
- background: url( ../images/external.png ) left top no-repeat;
- padding-left: 18px;
-}
-
-a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
- background: url( ../images/external.png ) right center no-repeat;
- padding-right: 18px;
-}
-
-#legend li.newWindow {
- background: url( ../images/newwindow.png ) left top no-repeat;
- padding-left: 18px;
-}
-
-a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover {
- background: url( ../images/newwindow.png ) right center no-repeat;
- padding-right: 18px;
-}
-
-p {
- line-height: 1.3em;
- font-size: small;
-}
-
-#breadcrumbs {
- border-top: 1px solid #fff;
- border-bottom: 1px solid #999;
- background-color: #F3B455;
- padding: 2px 8px;
-}
-
-#navcolumn h5 {
- color: gray;
- font-weight: bold;
- font-size: 11px;
- padding: 10px 0 1px 19px;
-}
-
-.source {
- border: 1px solid #999;
-}
-
-dl {
- padding: 4px 4px 4px 6px;
- border: 1px solid #aaa;
- background-color: #ffc;
-}
-
-dt {
- color: #900;
-}
-
-#organizationLogo img, #projectLogo img, #projectLogo span {
- margin: 8px;
-}
-
-#banner {
- border-bottom: 1px solid #fff;
- padding: 8px;
-}
-
-#breadcrumbs a:link {
- text-decoration: none;
-}
-
-#breadcrumbs a:visited {
- text-decoration: none;
- color: #333
-}
-
-#breadcrumbs a:hover {
- text-decoration: none;
- color: white
-}
-
-.errormark, .warningmark, .donemark, .infomark {
- background: url( ../images/icon_error_sml.gif ) no-repeat;
-}
-
-.warningmark {
- background-image: url( ../images/icon_warning_sml.gif );
-}
-
-.donemark {
- background-image: url( ../images/icon_success_sml.gif );
-}
-
-.infomark {
- background-image: url( ../images/icon_info_sml.gif );
-}
-
-.booleanIcon {
- padding-left: 20px;
- height: 20px;
-}
-
-pre.pom {
- font-size: 0.9em;
- border: 1px solid #ddddff;
- background-color: #f8f8ff;
- padding: 5px;
-}
-
-pre.pom code {
- font-size: 0.9em;
-}
-
-#leftColumn {
- padding: 4px 4px 4px 4px;
- overflow: hidden;
-}
-
-#navcolumn {
- padding: 6px 0 0 2px;
-}
-
-#navcolumn li {
- font-size: 9px;
- text-indent: 19px;
- line-height: 24px;
- height: 25px;
- width: 161px;
- background-image: url( ../images/super.gif );
- background-position: 0 0;
- background-repeat: no-repeat;
- display: block;
- padding-left: 0;
-}
-
-#navcolumn li li {
- padding-left: 16px;
- background: none;
- display: block;
-}
-
-#navcolumn li li a:hover {
- color: black !important;
- background: none;
- display: block;
-}
-
-#navcolumn li li a:active {
- color: red !important;
- background: none;
- display: block;
-}
-
-#navcolumn li.collapsed {
- background-image: url( ../images/super.gif );
-}
-
-#navcolumn li.expanded {
- background-image: url( ../images/super.gif );
- height: inherit;
-}
-
-#navcolumn li a:link {
- color: #666;
- display: block;
-}
-
-#navcolumn li a:hover {
- color: #fff !important;
- background: url( ../images/super_hl.gif ) 0 -25px no-repeat;
- display: block;
-}
-
-#navcolumn li a:active {
- color: #fff !important;
- background: url( ../images/super_hl.gif ) 0 -50px no-repeat;
- display: block;
-}
-
-#navcolumn li a:visited {
- color: #666;
- display: block;
-}
-
-#navcolumn li ul li {
- color: #333 !important;
- text-indent: 30px !important;
- line-height: 20px !important;
- height: 20px !important;
- background-image: url( ../images/supersub.gif ) !important;
- font-size: 9px;
- width: 161px;
- background-repeat: no-repeat;
- display: block;
- padding-left: 0;
-}
-
-#navcolumn li ul li a:hover {
- color: #fff !important;
- background: url( ../images/super_hl_sub.gif ) 0 -20px no-repeat;
- background-position: right;
- width: 161px;
- display: block;
-}
-
-#footer {
- background: url( ../images/footerborder.gif ) 0 5px repeat-x;
- padding: 14px 4px 12px 4px;
- margin-top: 2em;
-}
-
-a:link, a:visited {
- color: #333;
-}
-
-#navcolumn a {
- text-decoration: none;
-}
-
-a:active, a:hover {
- color: #f30;
-}
-
-blockquote {
- border-left: 1px solid #DFDEDE;
- padding-left: 1em;
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn {
- display: none !important;
-}
-
-#bodyColumn, body.docs div.docs {
- margin: 0 !important;
- border: none !important
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-.sidebar3 {
- width: 10em;
- float: right;
- text-align: center;
-}
-
-#sidebarb {
- font-size: small;
- text-align: center;
- padding: 10px 10px 10px 10px;
- border: 1px #DFDEDE solid;
- width: 10em;
-}
-
-#sidebar {
- float: right;
- font-size: small;
- margin: 10px;
- padding: 10px;
- border: 1px #DFDEDE solid;
- width: 10em;
-}
-
-.download {
- float: right;
- font-size: small;
- font-weight: bold;
- xmargin: 0px auto;
- margin: 15px auto 0px auto;
- height: auto;
- width: 150px;
- min-width: 120px;
- display: block;
-}
-
-.download .hd .c,
-.download .ft .c {
- font-size: 1px; /* ensure minimum height */
- height: 10px;
-}
-
-.download .ft .c {
- height: 10px;
-}
-
-.download .hd {
- background: transparent url(../images/download.tl.gif) no-repeat 0px 0px;
-}
-
-.download .hd .c {
- background: transparent url(../images/download.tr.gif) no-repeat right 0px;
-}
-
-.download .bd {
- background: transparent url(../images/download.ml.gif) repeat-y 0px 0px;
-}
-
-.download .bd .c {
- background: transparent url(../images/download.mr.gif) repeat-y right 0px;
-}
-
-.download .bd .c .s {
- margin: 0px 8px 0px 4px;
- background: #000 url(../images/download.ms.jpg) repeat-x 0px 0px;
- padding: 1em;
-}
-
-.download .ft {
- background: transparent url(../images/download.bl.gif) no-repeat 0px 0px;
-}
-
-.download .ft .c {
- background: transparent url(../images/download.br.gif) no-repeat right 0px;
-}
-
-.download .bd h2 {
- margin: 0px;
- text-align: center;
- border-bottom-width: 0px !important;
-}
-
-.download .bd p {
- margin: 0px;
- border: 0px;
- text-align: left;
- padding-left: 15px;
-}
-
-.download a {
- text-decoration: none;
-}
-
-#contentArea {
- /* margin-right: 15em; */
- padding: 1em;
-}
-
-#tabs b {
- border: 1px #DFDEDE solid;
- padding-left: 1em;
- padding-right: 1em;
-}
-
-#tabs a {
- border: 1px #DFDEDE solid;
- padding-left: 1em;
- padding-right: 1em;
- text-decoration: none;
-}
-
-#tabArea {
- border-top: 1px solid #DFDEDE;
- padding: 1em;
-}
-
-#searchTypes {
- text-align: right;
- font-size: xx-small;
-}
-
-.statusFailed {
- color: red;
- font-weight: bold;
-}
-
-/* WebWork validation failures */
-.errorMessage {
- color: red;
- font-weight: bold;
-}
-
-.actionMessage {
- font-weight: bold;
-}
-
-.errorBullet {
- list-style-image: url( "../images/icon_error_sml.gif" );
-}
-
-.warningBullet {
- list-style-image: url( "../images/icon_warning_sml.gif" );
-}
-
-.infoBullet {
- list-style-image: url( "../images/icon_info_sml.gif" );
-}
-
-.artifact-link {
- font-size: x-small;
- padding-left: 5em;
-}
-
-.artifact-title {
-
-}
-
-ul.dependencyTree {
- margin-left: 50px;
-}
-
-ul.dependencyTree span.artifact-link {
- padding-left: 0px;
-}
-
-.eXtremeTable tr.filter {
- padding: 1px;
-}
-
-.eXtremeTable .tableRegion,.eXtremeTable .statusBar {
- width: 100%;
-}
-
-.eXtremeTable .tableHeader {
- background-color: #F3B455;
-}
-
-.eXtremeTable .tableHeaderSort {
- background-color: #FFBF5F;
-}
-
-.eXtremeTable .compactToolbar td {
- white-space: nowrap;
-}
-
-.tools {
- border-color: gray !important;
-}
-
-.tools .toolHeading {
- padding: 0px 3px 0px 3px;
- margin: 0px !important;
- font-size: 11px !important;
- background-color: #F3B455 !important;
-}
-
+++ /dev/null
-<%--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- --%>
-
-<%response.sendRedirect( request.getContextPath() + "/index.action" );%>
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-// script.aculo.us builder.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
-
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-//
-// See scriptaculous.js for full license.
-
-var Builder = {
- NODEMAP: {
- AREA: 'map',
- CAPTION: 'table',
- COL: 'table',
- COLGROUP: 'table',
- LEGEND: 'fieldset',
- OPTGROUP: 'select',
- OPTION: 'select',
- PARAM: 'object',
- TBODY: 'table',
- TD: 'table',
- TFOOT: 'table',
- TH: 'table',
- THEAD: 'table',
- TR: 'table'
- },
-// note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
-// due to a Firefox bug
- node: function( elementName )
- {
- elementName = elementName.toUpperCase();
-
- // try innerHTML approach
- var parentTag = this.NODEMAP[elementName] || 'div';
- var parentElement = document.createElement(parentTag);
- try
- { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
- parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
- }
- catch( e )
- {
- }
- var element = parentElement.firstChild || null;
-
- // see if browser added wrapping tags
- if ( element && (element.tagName != elementName) )
- element = element.getElementsByTagName(elementName)[0];
-
- // fallback to createElement approach
- if ( !element ) element = document.createElement(elementName);
-
- // abort if nothing could be created
- if ( !element ) return;
-
- // attributes (or text)
- if ( arguments[1] )
- if ( this._isStringOrNumber(arguments[1]) || (arguments[1] instanceof Array) )
- {
- this._children(element, arguments[1]);
- }
- else
- {
- var attrs = this._attributes(arguments[1]);
- if ( attrs.length )
- {
- try
- { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
- parentElement.innerHTML = "<" + elementName + " " + attrs + "></" + elementName + ">";
- }
- catch( e )
- {
- }
- element = parentElement.firstChild || null;
- // workaround firefox 1.0.X bug
- if ( !element )
- {
- element = document.createElement(elementName);
- for ( attr in arguments[1] )
- element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
- }
- if ( element.tagName != elementName )
- element = parentElement.getElementsByTagName(elementName)[0];
- }
- }
-
- // text, or array of children
- if ( arguments[2] )
- this._children(element, arguments[2]);
-
- return element;
- },
- _text: function( text )
- {
- return document.createTextNode(text);
- },
- _attributes: function( attributes )
- {
- var attrs = [];
- for ( attribute in attributes )
- attrs.push((attribute == 'className' ? 'class' : attribute) + '="' +
- attributes[attribute].toString().escapeHTML() + '"');
- return attrs.join(" ");
- },
- _children: function( element, children )
- {
- if ( typeof children == 'object' )
- { // array can hold nodes and text
- children.flatten().each(function( e )
- {
- if ( typeof e == 'object' )
- element.appendChild(e)
- else
- if ( Builder._isStringOrNumber(e) )
- element.appendChild(Builder._text(e));
- });
- }
- else
- if ( Builder._isStringOrNumber(children) )
- element.appendChild(Builder._text(children));
- },
- _isStringOrNumber: function( param )
- {
- return(typeof param == 'string' || typeof param == 'number');
- },
- dump: function( scope )
- {
- if ( typeof scope != 'object' && typeof scope != 'function' ) scope = window; //global scope
-
- var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
- "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
- "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX " +
- "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P " +
- "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD " +
- "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
-
- tags.each(function( tag )
- {
- scope[tag] = function()
- {
- return Builder.node.apply(Builder, [tag].concat($A(arguments)));
- }
- });
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-// script.aculo.us controls.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
-
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-// (c) 2005 Jon Tirsen (http://www.tirsen.com)
-// Contributors:
-// Richard Livsey
-// Rahul Bhargava
-// Rob Wills
-//
-// See scriptaculous.js for full license.
-
-// Autocompleter.Base handles all the autocompletion functionality
-// that's independent of the data source for autocompletion. This
-// includes drawing the autocompletion menu, observing keyboard
-// and mouse events, and similar.
-//
-// Specific autocompleters need to provide, at the very least,
-// a getUpdatedChoices function that will be invoked every time
-// the text inside the monitored textbox changes. This method
-// should get the text for which to provide autocompletion by
-// invoking this.getToken(), NOT by directly accessing
-// this.element.value. This is to allow incremental tokenized
-// autocompletion. Specific auto-completion logic (AJAX, etc)
-// belongs in getUpdatedChoices.
-//
-// Tokenized incremental autocompletion is enabled automatically
-// when an autocompleter is instantiated with the 'tokens' option
-// in the options parameter, e.g.:
-// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
-// will incrementally autocomplete with a comma as the token.
-// Additionally, ',' in the above example can be replaced with
-// a token array, e.g. { tokens: [',', '\n'] } which
-// enables autocompletion on multiple tokens. This is most
-// useful when one of the tokens is \n (a newline), as it
-// allows smart autocompletion after linebreaks.
-
-if ( typeof Effect == 'undefined' )
- throw("controls.js requires including script.aculo.us' effects.js library");
-
-var Autocompleter = {}
-Autocompleter.Base = function()
-{
-};
-Autocompleter.Base.prototype = {
- baseInitialize: function( element, update, options )
- {
- this.element = $(element);
- this.update = $(update);
- this.hasFocus = false;
- this.changed = false;
- this.active = false;
- this.index = 0;
- this.entryCount = 0;
-
- if ( this.setOptions )
- this.setOptions(options);
- else
- this.options = options || {};
-
- this.options.paramName = this.options.paramName || this.element.name;
- this.options.tokens = this.options.tokens || [];
- this.options.frequency = this.options.frequency || 0.4;
- this.options.minChars = this.options.minChars || 1;
- this.options.onShow = this.options.onShow || function( element, update )
- {
- if ( !update.style.position || update.style.position == 'absolute' )
- {
- update.style.position = 'absolute';
- Position.clone(element, update, {
- setHeight: false,
- offsetTop: element.offsetHeight
- });
- }
- Effect.Appear(update, {duration:0.15});
- };
- this.options.onHide = this.options.onHide || function( element, update )
- {
- new Effect.Fade(update, {duration:0.15})
- };
-
- if ( typeof(this.options.tokens) == 'string' )
- this.options.tokens = new Array(this.options.tokens);
-
- this.observer = null;
-
- this.element.setAttribute('autocomplete', 'off');
-
- Element.hide(this.update);
-
- Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
- Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
- },
-
- show: function()
- {
- if ( Element.getStyle(this.update, 'display') == 'none' ) this.options.onShow(this.element, this.update);
- if ( !this.iefix && (navigator.appVersion.indexOf('MSIE') > 0) && (navigator.userAgent.indexOf('Opera') < 0) &&
- (Element.getStyle(this.update, 'position') == 'absolute') )
- {
- new Insertion.After(this.update, '<iframe id="' + this.update.id + '_iefix" ' +
- 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
- 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
- this.iefix = $(this.update.id + '_iefix');
- }
- if ( this.iefix ) setTimeout(this.fixIEOverlapping.bind(this), 50);
- },
-
- fixIEOverlapping: function()
- {
- Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
- this.iefix.style.zIndex = 1;
- this.update.style.zIndex = 2;
- Element.show(this.iefix);
- },
-
- hide: function()
- {
- this.stopIndicator();
- if ( Element.getStyle(this.update, 'display') != 'none' ) this.options.onHide(this.element, this.update);
- if ( this.iefix ) Element.hide(this.iefix);
- },
-
- startIndicator: function()
- {
- if ( this.options.indicator ) Element.show(this.options.indicator);
- },
-
- stopIndicator: function()
- {
- if ( this.options.indicator ) Element.hide(this.options.indicator);
- },
-
- onKeyPress: function( event )
- {
- if ( this.active )
- switch ( event.keyCode )
- {
- case Event.KEY_TAB:
- case Event.KEY_RETURN:
- this.selectEntry();
- Event.stop(event);
- case Event.KEY_ESC:
- this.hide();
- this.active = false;
- Event.stop(event);
- return;
- case Event.KEY_LEFT:
- case Event.KEY_RIGHT:
- return;
- case Event.KEY_UP:
- this.markPrevious();
- this.render();
- if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) Event.stop(event);
- return;
- case Event.KEY_DOWN:
- this.markNext();
- this.render();
- if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) Event.stop(event);
- return;
- }
- else
- if ( event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN ||
- (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0) ) return;
-
- this.changed = true;
- this.hasFocus = true;
-
- if ( this.observer ) clearTimeout(this.observer);
- this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency * 1000);
- },
-
- activate: function()
- {
- this.changed = false;
- this.hasFocus = true;
- this.getUpdatedChoices();
- },
-
- onHover: function( event )
- {
- var element = Event.findElement(event, 'LI');
- if ( this.index != element.autocompleteIndex )
- {
- this.index = element.autocompleteIndex;
- this.render();
- }
- Event.stop(event);
- },
-
- onClick: function( event )
- {
- var element = Event.findElement(event, 'LI');
- this.index = element.autocompleteIndex;
- this.selectEntry();
- this.hide();
- },
-
- onBlur: function( event )
- {
- // needed to make click events working
- setTimeout(this.hide.bind(this), 250);
- this.hasFocus = false;
- this.active = false;
- },
-
- render: function()
- {
- if ( this.entryCount > 0 )
- {
- for ( var i = 0; i < this.entryCount; i++ )
- this.index == i ? Element.addClassName(this.getEntry(i), "selected")
- : Element.removeClassName(this.getEntry(i), "selected");
-
- if ( this.hasFocus )
- {
- this.show();
- this.active = true;
- }
- }
- else
- {
- this.active = false;
- this.hide();
- }
- },
-
- markPrevious: function()
- {
- if ( this.index > 0 ) this.index--
- else this.index = this.entryCount - 1;
- this.getEntry(this.index).scrollIntoView(true);
- },
-
- markNext: function()
- {
- if ( this.index < this.entryCount - 1 ) this.index++
- else this.index = 0;
- this.getEntry(this.index).scrollIntoView(false);
- },
-
- getEntry: function( index )
- {
- return this.update.firstChild.childNodes[index];
- },
-
- getCurrentEntry: function()
- {
- return this.getEntry(this.index);
- },
-
- selectEntry: function()
- {
- this.active = false;
- this.updateElement(this.getCurrentEntry());
- },
-
- updateElement: function( selectedElement )
- {
- if ( this.options.updateElement )
- {
- this.options.updateElement(selectedElement);
- return;
- }
- var value = '';
- if ( this.options.select )
- {
- var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
- if ( nodes.length > 0 ) value = Element.collectTextNodes(nodes[0], this.options.select);
- }
- else
- value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
-
- var lastTokenPos = this.findLastToken();
- if ( lastTokenPos != -1 )
- {
- var newValue = this.element.value.substr(0, lastTokenPos + 1);
- var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
- if ( whitespace )
- newValue += whitespace[0];
- this.element.value = newValue + value;
- }
- else
- {
- this.element.value = value;
- }
- this.element.focus();
-
- if ( this.options.afterUpdateElement )
- this.options.afterUpdateElement(this.element, selectedElement);
- },
-
- updateChoices: function( choices )
- {
- if ( !this.changed && this.hasFocus )
- {
- this.update.innerHTML = choices;
- Element.cleanWhitespace(this.update);
- Element.cleanWhitespace(this.update.firstChild);
-
- if ( this.update.firstChild && this.update.firstChild.childNodes )
- {
- this.entryCount = this.update.firstChild.childNodes.length;
- for ( var i = 0; i < this.entryCount; i++ )
- {
- var entry = this.getEntry(i);
- entry.autocompleteIndex = i;
- this.addObservers(entry);
- }
- }
- else
- {
- this.entryCount = 0;
- }
-
- this.stopIndicator();
- this.index = 0;
-
- if ( this.entryCount == 1 && this.options.autoSelect )
- {
- this.selectEntry();
- this.hide();
- }
- else
- {
- this.render();
- }
- }
- },
-
- addObservers: function( element )
- {
- Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
- Event.observe(element, "click", this.onClick.bindAsEventListener(this));
- },
-
- onObserverEvent: function()
- {
- this.changed = false;
- if ( this.getToken().length >= this.options.minChars )
- {
- this.startIndicator();
- this.getUpdatedChoices();
- }
- else
- {
- this.active = false;
- this.hide();
- }
- },
-
- getToken: function()
- {
- var tokenPos = this.findLastToken();
- if ( tokenPos != -1 )
- var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/, '').replace(/\s+$/, '');
- else
- var ret = this.element.value;
-
- return /\n/.test(ret) ? '' : ret;
- },
-
- findLastToken: function()
- {
- var lastTokenPos = -1;
-
- for ( var i = 0; i < this.options.tokens.length; i++ )
- {
- var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
- if ( thisTokenPos > lastTokenPos )
- lastTokenPos = thisTokenPos;
- }
- return lastTokenPos;
- }
-}
-
-Ajax.Autocompleter = Class.create();
-Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
- initialize: function( element, update, url, options )
- {
- this.baseInitialize(element, update, options);
- this.options.asynchronous = true;
- this.options.onComplete = this.onComplete.bind(this);
- this.options.defaultParams = this.options.parameters || null;
- this.url = url;
- },
-
- getUpdatedChoices: function()
- {
- entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.getToken());
-
- this.options.parameters = this.options.callback ? this.options.callback(this.element, entry) : entry;
-
- if ( this.options.defaultParams )
- this.options.parameters += '&' + this.options.defaultParams;
-
- new Ajax.Request(this.url, this.options);
- },
-
- onComplete: function( request )
- {
- this.updateChoices(request.responseText);
- }
-
-});
-
-// The local array autocompleter. Used when you'd prefer to
-// inject an array of autocompletion options into the page, rather
-// than sending out Ajax queries, which can be quite slow sometimes.
-//
-// The constructor takes four parameters. The first two are, as usual,
-// the id of the monitored textbox, and id of the autocompletion menu.
-// The third is the array you want to autocomplete from, and the fourth
-// is the options block.
-//
-// Extra local autocompletion options:
-// - choices - How many autocompletion choices to offer
-//
-// - partialSearch - If false, the autocompleter will match entered
-// text only at the beginning of strings in the
-// autocomplete array. Defaults to true, which will
-// match text at the beginning of any *word* in the
-// strings in the autocomplete array. If you want to
-// search anywhere in the string, additionally set
-// the option fullSearch to true (default: off).
-//
-// - fullSsearch - Search anywhere in autocomplete array strings.
-//
-// - partialChars - How many characters to enter before triggering
-// a partial match (unlike minChars, which defines
-// how many characters are required to do any match
-// at all). Defaults to 2.
-//
-// - ignoreCase - Whether to ignore case when autocompleting.
-// Defaults to true.
-//
-// It's possible to pass in a custom function as the 'selector'
-// option, if you prefer to write your own autocompletion logic.
-// In that case, the other options above will not apply unless
-// you support them.
-
-Autocompleter.Local = Class.create();
-Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
- initialize: function( element, update, array, options )
- {
- this.baseInitialize(element, update, options);
- this.options.array = array;
- },
-
- getUpdatedChoices: function()
- {
- this.updateChoices(this.options.selector(this));
- },
-
- setOptions: function( options )
- {
- this.options = Object.extend({
- choices: 10,
- partialSearch: true,
- partialChars: 2,
- ignoreCase: true,
- fullSearch: false,
- selector: function( instance )
- {
- var ret = [];
- // Beginning matches
- var partial = [];
- // Inside matches
- var entry = instance.getToken();
- var count = 0;
-
- for ( var i = 0; i < instance.options.array.length && ret.length < instance.options.choices; i++ )
- {
-
- var elem = instance.options.array[i];
- var foundPos = instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase())
- : elem.indexOf(entry);
-
- while ( foundPos != -1 )
- {
- if ( foundPos == 0 && elem.length != entry.length )
- {
- ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
- elem.substr(entry.length) + "</li>");
- break;
- }
- else if ( entry.length >= instance.options.partialChars && instance.options.partialSearch &&
- foundPos != -1 )
- {
- if ( instance.options.fullSearch || /\s/.test(elem.substr(foundPos - 1, 1)) )
- {
- partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
- elem.substr(foundPos, entry.length) + "</strong>" +
- elem.substr(foundPos + entry.length) + "</li>");
- break;
- }
- }
-
- foundPos =
- instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1)
- : elem.indexOf(entry, foundPos + 1);
-
- }
- }
- if ( partial.length )
- ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
- return "<ul>" + ret.join('') + "</ul>";
- }
- }, options || {});
- }
-});
-
-// AJAX in-place editor
-//
-// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
-
-// Use this if you notice weird scrolling problems on some browsers,
-// the DOM might be a bit confused when this gets called so do this
-// waits 1 ms (with setTimeout) until it does the activation
-Field.scrollFreeActivate = function( field )
-{
- setTimeout(function()
- {
- Field.activate(field);
- }, 1);
-}
-
-Ajax.InPlaceEditor = Class.create();
-Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
-Ajax.InPlaceEditor.prototype = {
- initialize: function( element, url, options )
- {
- this.url = url;
- this.element = $(element);
-
- this.options = Object.extend({
- okButton: true,
- okText: "ok",
- cancelLink: true,
- cancelText: "cancel",
- savingText: "Saving...",
- clickToEditText: "Click to edit",
- okText: "ok",
- rows: 1,
- onComplete: function( transport, element )
- {
- new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
- },
- onFailure: function( transport )
- {
- alert("Error communicating with the server: " + transport.responseText.stripTags());
- },
- callback: function( form )
- {
- return Form.serialize(form);
- },
- handleLineBreaks: true,
- loadingText: 'Loading...',
- savingClassName: 'inplaceeditor-saving',
- loadingClassName: 'inplaceeditor-loading',
- formClassName: 'inplaceeditor-form',
- highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
- highlightendcolor: "#FFFFFF",
- externalControl: null,
- submitOnBlur: false,
- ajaxOptions: {},
- evalScripts: false
- }, options || {});
-
- if ( !this.options.formId && this.element.id )
- {
- this.options.formId = this.element.id + "-inplaceeditor";
- if ( $(this.options.formId) )
- {
- // there's already a form with that name, don't specify an id
- this.options.formId = null;
- }
- }
-
- if ( this.options.externalControl )
- {
- this.options.externalControl = $(this.options.externalControl);
- }
-
- this.originalBackground = Element.getStyle(this.element, 'background-color');
- if ( !this.originalBackground )
- {
- this.originalBackground = "transparent";
- }
-
- this.element.title = this.options.clickToEditText;
-
- this.onclickListener = this.enterEditMode.bindAsEventListener(this);
- this.mouseoverListener = this.enterHover.bindAsEventListener(this);
- this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
- Event.observe(this.element, 'click', this.onclickListener);
- Event.observe(this.element, 'mouseover', this.mouseoverListener);
- Event.observe(this.element, 'mouseout', this.mouseoutListener);
- if ( this.options.externalControl )
- {
- Event.observe(this.options.externalControl, 'click', this.onclickListener);
- Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
- Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
- }
- },
- enterEditMode: function( evt )
- {
- if ( this.saving ) return;
- if ( this.editing ) return;
- this.editing = true;
- this.onEnterEditMode();
- if ( this.options.externalControl )
- {
- Element.hide(this.options.externalControl);
- }
- Element.hide(this.element);
- this.createForm();
- this.element.parentNode.insertBefore(this.form, this.element);
- if ( !this.options.loadTextURL ) Field.scrollFreeActivate(this.editField);
- // stop the event to avoid a page refresh in Safari
- if ( evt )
- {
- Event.stop(evt);
- }
- return false;
- },
- createForm: function()
- {
- this.form = document.createElement("form");
- this.form.id = this.options.formId;
- Element.addClassName(this.form, this.options.formClassName)
- this.form.onsubmit = this.onSubmit.bind(this);
-
- this.createEditField();
-
- if ( this.options.textarea )
- {
- var br = document.createElement("br");
- this.form.appendChild(br);
- }
-
- if ( this.options.okButton )
- {
- okButton = document.createElement("input");
- okButton.type = "submit";
- okButton.value = this.options.okText;
- okButton.className = 'editor_ok_button';
- this.form.appendChild(okButton);
- }
-
- if ( this.options.cancelLink )
- {
- cancelLink = document.createElement("a");
- cancelLink.href = "#";
- cancelLink.appendChild(document.createTextNode(this.options.cancelText));
- cancelLink.onclick = this.onclickCancel.bind(this);
- cancelLink.className = 'editor_cancel';
- this.form.appendChild(cancelLink);
- }
- },
- hasHTMLLineBreaks: function( string )
- {
- if ( !this.options.handleLineBreaks ) return false;
- return string.match(/<br/i) || string.match(/<p>/i);
- },
- convertHTMLLineBreaks: function( string )
- {
- return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
- },
- createEditField: function()
- {
- var text;
- if ( this.options.loadTextURL )
- {
- text = this.options.loadingText;
- }
- else
- {
- text = this.getText();
- }
-
- var obj = this;
-
- if ( this.options.rows == 1 && !this.hasHTMLLineBreaks(text) )
- {
- this.options.textarea = false;
- var textField = document.createElement("input");
- textField.obj = this;
- textField.type = "text";
- textField.name = "value";
- textField.value = text;
- textField.style.backgroundColor = this.options.highlightcolor;
- textField.className = 'editor_field';
- var size = this.options.size || this.options.cols || 0;
- if ( size != 0 ) textField.size = size;
- if ( this.options.submitOnBlur )
- textField.onblur = this.onSubmit.bind(this);
- this.editField = textField;
- }
- else
- {
- this.options.textarea = true;
- var textArea = document.createElement("textarea");
- textArea.obj = this;
- textArea.name = "value";
- textArea.value = this.convertHTMLLineBreaks(text);
- textArea.rows = this.options.rows;
- textArea.cols = this.options.cols || 40;
- textArea.className = 'editor_field';
- if ( this.options.submitOnBlur )
- textArea.onblur = this.onSubmit.bind(this);
- this.editField = textArea;
- }
-
- if ( this.options.loadTextURL )
- {
- this.loadExternalText();
- }
- this.form.appendChild(this.editField);
- },
- getText: function()
- {
- return this.element.innerHTML;
- },
- loadExternalText: function()
- {
- Element.addClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = true;
- new Ajax.Request(this.options.loadTextURL, Object.extend({
- asynchronous: true,
- onComplete: this.onLoadedExternalText.bind(this)
- }, this.options.ajaxOptions));
- },
- onLoadedExternalText: function( transport )
- {
- Element.removeClassName(this.form, this.options.loadingClassName);
- this.editField.disabled = false;
- this.editField.value = transport.responseText.stripTags();
- Field.scrollFreeActivate(this.editField);
- },
- onclickCancel: function()
- {
- this.onComplete();
- this.leaveEditMode();
- return false;
- },
- onFailure: function( transport )
- {
- this.options.onFailure(transport);
- if ( this.oldInnerHTML )
- {
- this.element.innerHTML = this.oldInnerHTML;
- this.oldInnerHTML = null;
- }
- return false;
- },
- onSubmit: function()
- {
- // onLoading resets these so we need to save them away for the Ajax call
- var form = this.form;
- var value = this.editField.value;
-
- // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
- // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
- // to be displayed indefinitely
- this.onLoading();
-
- if ( this.options.evalScripts )
- {
- new Ajax.Request(this.url, Object.extend({
- parameters: this.options.callback(form, value),
- onComplete: this.onComplete.bind(this),
- onFailure: this.onFailure.bind(this),
- asynchronous:true,
- evalScripts:true
- }, this.options.ajaxOptions));
- }
- else
- {
- new Ajax.Updater({ success: this.element,
- // don't update on failure (this could be an option)
- failure: null }, this.url, Object.extend({
- parameters: this.options.callback(form, value),
- onComplete: this.onComplete.bind(this),
- onFailure: this.onFailure.bind(this)
- }, this.options.ajaxOptions));
- }
- // stop the event to avoid a page refresh in Safari
- if ( arguments.length > 1 )
- {
- Event.stop(arguments[0]);
- }
- return false;
- },
- onLoading: function()
- {
- this.saving = true;
- this.removeForm();
- this.leaveHover();
- this.showSaving();
- },
- showSaving: function()
- {
- this.oldInnerHTML = this.element.innerHTML;
- this.element.innerHTML = this.options.savingText;
- Element.addClassName(this.element, this.options.savingClassName);
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
- },
- removeForm: function()
- {
- if ( this.form )
- {
- if ( this.form.parentNode ) Element.remove(this.form);
- this.form = null;
- }
- },
- enterHover: function()
- {
- if ( this.saving ) return;
- this.element.style.backgroundColor = this.options.highlightcolor;
- if ( this.effect )
- {
- this.effect.cancel();
- }
- Element.addClassName(this.element, this.options.hoverClassName)
- },
- leaveHover: function()
- {
- if ( this.options.backgroundColor )
- {
- this.element.style.backgroundColor = this.oldBackground;
- }
- Element.removeClassName(this.element, this.options.hoverClassName)
- if ( this.saving ) return;
- this.effect = new Effect.Highlight(this.element, {
- startcolor: this.options.highlightcolor,
- endcolor: this.options.highlightendcolor,
- restorecolor: this.originalBackground
- });
- },
- leaveEditMode: function()
- {
- Element.removeClassName(this.element, this.options.savingClassName);
- this.removeForm();
- this.leaveHover();
- this.element.style.backgroundColor = this.originalBackground;
- Element.show(this.element);
- if ( this.options.externalControl )
- {
- Element.show(this.options.externalControl);
- }
- this.editing = false;
- this.saving = false;
- this.oldInnerHTML = null;
- this.onLeaveEditMode();
- },
- onComplete: function( transport )
- {
- this.leaveEditMode();
- this.options.onComplete.bind(this)(transport, this.element);
- },
- onEnterEditMode: function()
- {
- },
- onLeaveEditMode: function()
- {
- },
- dispose: function()
- {
- if ( this.oldInnerHTML )
- {
- this.element.innerHTML = this.oldInnerHTML;
- }
- this.leaveEditMode();
- Event.stopObserving(this.element, 'click', this.onclickListener);
- Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
- if ( this.options.externalControl )
- {
- Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
- Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
- Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
- }
- }
-};
-
-Ajax.InPlaceCollectionEditor = Class.create();
-Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
-Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
- createEditField: function()
- {
- if ( !this.cached_selectTag )
- {
- var selectTag = document.createElement("select");
- var collection = this.options.collection || [];
- var optionTag;
- collection.each(function( e, i )
- {
- optionTag = document.createElement("option");
- optionTag.value = (e instanceof Array) ? e[0] : e;
- if ( (typeof this.options.value == 'undefined') &&
- ((e instanceof Array) ? this.element.innerHTML == e[1] : e ==
- optionTag.value) ) optionTag.selected =
- true;
- if ( this.options.value == optionTag.value ) optionTag.selected = true;
- optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
- selectTag.appendChild(optionTag);
- }.bind(this));
- this.cached_selectTag = selectTag;
- }
-
- this.editField = this.cached_selectTag;
- if ( this.options.loadTextURL ) this.loadExternalText();
- this.form.appendChild(this.editField);
- this.options.callback = function( form, value )
- {
- return "value=" + encodeURIComponent(value);
- }
- }
-});
-
-// Delayed observer, like Form.Element.Observer,
-// but waits for delay after last key input
-// Ideal for live-search fields
-
-Form.Element.DelayedObserver = Class.create();
-Form.Element.DelayedObserver.prototype = {
- initialize: function( element, delay, callback )
- {
- this.delay = delay || 0.5;
- this.element = $(element);
- this.callback = callback;
- this.timer = null;
- this.lastValue = $F(this.element);
- Event.observe(this.element, 'keyup', this.delayedListener.bindAsEventListener(this));
- },
- delayedListener: function( event )
- {
- if ( this.lastValue == $F(this.element) ) return;
- if ( this.timer ) clearTimeout(this.timer);
- this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
- this.lastValue = $F(this.element);
- },
- onTimerEvent: function()
- {
- this.timer = null;
- this.callback(this.element, $F(this.element));
- }
-};
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-// script.aculo.us dragdrop.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
-
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
-//
-// See scriptaculous.js for full license.
-
-/*--------------------------------------------------------------------------*/
-
-if ( typeof Effect == 'undefined' )
- throw("dragdrop.js requires including script.aculo.us' effects.js library");
-
-var Droppables = {
- drops: [],
-
- remove: function( element )
- {
- this.drops = this.drops.reject(function( d )
- {
- return d.element == $(element)
- });
- },
-
- add: function( element )
- {
- element = $(element);
- var options = Object.extend({
- greedy: true,
- hoverclass: null,
- tree: false
- }, arguments[1] || {});
-
- // cache containers
- if ( options.containment )
- {
- options._containers = [];
- var containment = options.containment;
- if ( (typeof containment == 'object') && (containment.constructor == Array) )
- {
- containment.each(function( c )
- {
- options._containers.push($(c))
- });
- }
- else
- {
- options._containers.push($(containment));
- }
- }
-
- if ( options.accept ) options.accept = [options.accept].flatten();
-
- Element.makePositioned(element);
- // fix IE
- options.element = element;
-
- this.drops.push(options);
- },
-
- findDeepestChild: function( drops )
- {
- deepest = drops[0];
-
- for ( i = 1; i < drops.length; ++i )
- if ( Element.isParent(drops[i].element, deepest.element) )
- deepest = drops[i];
-
- return deepest;
- },
-
- isContained: function( element, drop )
- {
- var containmentNode;
- if ( drop.tree )
- {
- containmentNode = element.treeNode;
- }
- else
- {
- containmentNode = element.parentNode;
- }
- return drop._containers.detect(function( c )
- {
- return containmentNode == c
- });
- },
-
- isAffected: function( point, element, drop )
- {
- return (
- (drop.element != element) && ((!drop._containers) || this.isContained(element, drop)) &&
- ((!drop.accept) || (Element.classNames(element).detect(function( v )
- {
- return drop.accept.include(v)
- }) )) && Position.within(drop.element, point[0], point[1]) );
- },
-
- deactivate: function( drop )
- {
- if ( drop.hoverclass )
- Element.removeClassName(drop.element, drop.hoverclass);
- this.last_active = null;
- },
-
- activate: function( drop )
- {
- if ( drop.hoverclass )
- Element.addClassName(drop.element, drop.hoverclass);
- this.last_active = drop;
- },
-
- show: function( point, element )
- {
- if ( !this.drops.length ) return;
- var affected = [];
-
- if ( this.last_active ) this.deactivate(this.last_active);
- this.drops.each(function( drop )
- {
- if ( Droppables.isAffected(point, element, drop) )
- affected.push(drop);
- });
-
- if ( affected.length > 0 )
- {
- drop = Droppables.findDeepestChild(affected);
- Position.within(drop.element, point[0], point[1]);
- if ( drop.onHover )
- drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
-
- Droppables.activate(drop);
- }
- },
-
- fire: function( event, element )
- {
- if ( !this.last_active ) return;
- Position.prepare();
-
- if ( this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active) )
- if ( this.last_active.onDrop )
- this.last_active.onDrop(element, this.last_active.element, event);
- },
-
- reset: function()
- {
- if ( this.last_active )
- this.deactivate(this.last_active);
- }
-}
-
-var Draggables = {
- drags: [],
- observers: [],
-
- register: function( draggable )
- {
- if ( this.drags.length == 0 )
- {
- this.eventMouseUp = this.endDrag.bindAsEventListener(this);
- this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
- this.eventKeypress = this.keyPress.bindAsEventListener(this);
-
- Event.observe(document, "mouseup", this.eventMouseUp);
- Event.observe(document, "mousemove", this.eventMouseMove);
- Event.observe(document, "keypress", this.eventKeypress);
- }
- this.drags.push(draggable);
- },
-
- unregister: function( draggable )
- {
- this.drags = this.drags.reject(function( d )
- {
- return d == draggable
- });
- if ( this.drags.length == 0 )
- {
- Event.stopObserving(document, "mouseup", this.eventMouseUp);
- Event.stopObserving(document, "mousemove", this.eventMouseMove);
- Event.stopObserving(document, "keypress", this.eventKeypress);
- }
- },
-
- activate: function( draggable )
- {
- if ( draggable.options.delay )
- {
- this._timeout = setTimeout(function()
- {
- Draggables._timeout = null;
- window.focus();
- Draggables.activeDraggable = draggable;
- }.bind(this), draggable.options.delay);
- }
- else
- {
- window.focus();
- // allows keypress events if window isn't currently focused, fails for Safari
- this.activeDraggable = draggable;
- }
- },
-
- deactivate: function()
- {
- this.activeDraggable = null;
- },
-
- updateDrag: function( event )
- {
- if ( !this.activeDraggable ) return;
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- // Mozilla-based browsers fire successive mousemove events with
- // the same coordinates, prevent needless redrawing (moz bug?)
- if ( this._lastPointer && (this._lastPointer.inspect() == pointer.inspect()) ) return;
- this._lastPointer = pointer;
-
- this.activeDraggable.updateDrag(event, pointer);
- },
-
- endDrag: function( event )
- {
- if ( this._timeout )
- {
- clearTimeout(this._timeout);
- this._timeout = null;
- }
- if ( !this.activeDraggable ) return;
- this._lastPointer = null;
- this.activeDraggable.endDrag(event);
- this.activeDraggable = null;
- },
-
- keyPress: function( event )
- {
- if ( this.activeDraggable )
- this.activeDraggable.keyPress(event);
- },
-
- addObserver: function( observer )
- {
- this.observers.push(observer);
- this._cacheObserverCallbacks();
- },
-
- removeObserver: function( element )
- { // element instead of observer fixes mem leaks
- this.observers = this.observers.reject(function( o )
- {
- return o.element == element
- });
- this._cacheObserverCallbacks();
- },
-
- notify: function( eventName, draggable, event )
- { // 'onStart', 'onEnd', 'onDrag'
- if ( this[eventName + 'Count'] > 0 )
- this.observers.each(function( o )
- {
- if ( o[eventName] ) o[eventName](eventName, draggable, event);
- });
- if ( draggable.options[eventName] ) draggable.options[eventName](draggable, event);
- },
-
- _cacheObserverCallbacks: function()
- {
- ['onStart','onEnd','onDrag'].each(function( eventName )
- {
- Draggables[eventName + 'Count'] = Draggables.observers.select(function( o )
- {
- return o[eventName];
- }).length;
- });
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Draggable = Class.create();
-Draggable._dragging = {};
-
-Draggable.prototype = {
- initialize: function( element )
- {
- var defaults = {
- handle: false,
- reverteffect: function( element, top_offset, left_offset )
- {
- var dur = Math.sqrt(Math.abs(top_offset ^ 2) + Math.abs(left_offset ^ 2)) * 0.02;
- new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
- queue: {scope:'_draggable', position:'end'}
- });
- },
- endeffect: function( element )
- {
- var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
- queue: {scope:'_draggable', position:'end'},
- afterFinish: function()
- {
- Draggable._dragging[element] = false
- }
- });
- },
- zindex: 1000,
- revert: false,
- scroll: false,
- scrollSensitivity: 20,
- scrollSpeed: 15,
- snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
- delay: 0
- };
-
- if ( arguments[1] && typeof arguments[1].endeffect == 'undefined' )
- Object.extend(defaults, {
- starteffect: function( element )
- {
- element._opacity = Element.getOpacity(element);
- Draggable._dragging[element] = true;
- new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
- }
- });
-
- var options = Object.extend(defaults, arguments[1] || {});
-
- this.element = $(element);
-
- if ( options.handle && (typeof options.handle == 'string') )
- {
- var h = Element.childrenWithClassName(this.element, options.handle, true);
- if ( h.length > 0 ) this.handle = h[0];
- }
- if ( !this.handle ) this.handle = $(options.handle);
- if ( !this.handle ) this.handle = this.element;
-
- if ( options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML )
- {
- options.scroll = $(options.scroll);
- this._isScrollChild = Element.childOf(this.element, options.scroll);
- }
-
- Element.makePositioned(this.element);
- // fix IE
-
- this.delta = this.currentDelta();
- this.options = options;
- this.dragging = false;
-
- this.eventMouseDown = this.initDrag.bindAsEventListener(this);
- Event.observe(this.handle, "mousedown", this.eventMouseDown);
-
- Draggables.register(this);
- },
-
- destroy: function()
- {
- Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
- Draggables.unregister(this);
- },
-
- currentDelta: function()
- {
- return([
- parseInt(Element.getStyle(this.element, 'left') || '0'),
- parseInt(Element.getStyle(this.element, 'top') || '0')]);
- },
-
- initDrag: function( event )
- {
- if ( typeof Draggable._dragging[this.element] != 'undefined' && Draggable._dragging[this.element] ) return;
- if ( Event.isLeftClick(event) )
- {
- // abort on form elements, fixes a Firefox issue
- var src = Event.element(event);
- if ( src.tagName && (
- src.tagName == 'INPUT' || src.tagName == 'SELECT' || src.tagName == 'OPTION' ||
- src.tagName == 'BUTTON' || src.tagName == 'TEXTAREA') ) return;
-
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var pos = Position.cumulativeOffset(this.element);
- this.offset = [0,1].map(function( i )
- {
- return (pointer[i] - pos[i])
- });
-
- Draggables.activate(this);
- Event.stop(event);
- }
- },
-
- startDrag: function( event )
- {
- this.dragging = true;
-
- if ( this.options.zindex )
- {
- this.originalZ = parseInt(Element.getStyle(this.element, 'z-index') || 0);
- this.element.style.zIndex = this.options.zindex;
- }
-
- if ( this.options.ghosting )
- {
- this._clone = this.element.cloneNode(true);
- Position.absolutize(this.element);
- this.element.parentNode.insertBefore(this._clone, this.element);
- }
-
- if ( this.options.scroll )
- {
- if ( this.options.scroll == window )
- {
- var where = this._getWindowScroll(this.options.scroll);
- this.originalScrollLeft = where.left;
- this.originalScrollTop = where.top;
- }
- else
- {
- this.originalScrollLeft = this.options.scroll.scrollLeft;
- this.originalScrollTop = this.options.scroll.scrollTop;
- }
- }
-
- Draggables.notify('onStart', this, event);
-
- if ( this.options.starteffect ) this.options.starteffect(this.element);
- },
-
- updateDrag: function( event, pointer )
- {
- if ( !this.dragging ) this.startDrag(event);
- Position.prepare();
- Droppables.show(pointer, this.element);
- Draggables.notify('onDrag', this, event);
-
- this.draw(pointer);
- if ( this.options.change ) this.options.change(this);
-
- if ( this.options.scroll )
- {
- this.stopScrolling();
-
- var p;
- if ( this.options.scroll == window )
- {
- with ( this._getWindowScroll(this.options.scroll) )
- {
- p = [ left, top, left + width, top + height ];
- }
- }
- else
- {
- p = Position.page(this.options.scroll);
- p[0] += this.options.scroll.scrollLeft;
- p[1] += this.options.scroll.scrollTop;
-
- p[0] += (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0);
- p[1] += (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
-
- p.push(p[0] + this.options.scroll.offsetWidth);
- p.push(p[1] + this.options.scroll.offsetHeight);
- }
- var speed = [0,0];
- if ( pointer[0] < (p[0] + this.options.scrollSensitivity) ) speed[0] = pointer[0] - (p[0] +
- this.options.scrollSensitivity);
- if ( pointer[1] < (p[1] + this.options.scrollSensitivity) ) speed[1] = pointer[1] - (p[1] +
- this.options.scrollSensitivity);
- if ( pointer[0] > (p[2] - this.options.scrollSensitivity) ) speed[0] = pointer[0] - (p[2] -
- this.options.scrollSensitivity);
- if ( pointer[1] > (p[3] - this.options.scrollSensitivity) ) speed[1] = pointer[1] - (p[3] -
- this.options.scrollSensitivity);
- this.startScrolling(speed);
- }
-
- // fix AppleWebKit rendering
- if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) window.scrollBy(0, 0);
-
- Event.stop(event);
- },
-
- finishDrag: function( event, success )
- {
- this.dragging = false;
-
- if ( this.options.ghosting )
- {
- Position.relativize(this.element);
- Element.remove(this._clone);
- this._clone = null;
- }
-
- if ( success ) Droppables.fire(event, this.element);
- Draggables.notify('onEnd', this, event);
-
- var revert = this.options.revert;
- if ( revert && typeof revert == 'function' ) revert = revert(this.element);
-
- var d = this.currentDelta();
- if ( revert && this.options.reverteffect )
- {
- this.options.reverteffect(this.element, d[1] - this.delta[1], d[0] - this.delta[0]);
- }
- else
- {
- this.delta = d;
- }
-
- if ( this.options.zindex )
- this.element.style.zIndex = this.originalZ;
-
- if ( this.options.endeffect )
- this.options.endeffect(this.element);
-
- Draggables.deactivate(this);
- Droppables.reset();
- },
-
- keyPress: function( event )
- {
- if ( event.keyCode != Event.KEY_ESC ) return;
- this.finishDrag(event, false);
- Event.stop(event);
- },
-
- endDrag: function( event )
- {
- if ( !this.dragging ) return;
- this.stopScrolling();
- this.finishDrag(event, true);
- Event.stop(event);
- },
-
- draw: function( point )
- {
- var pos = Position.cumulativeOffset(this.element);
- if ( this.options.ghosting )
- {
- var r = Position.realOffset(this.element);
- window.status = r.inspect();
- pos[0] += r[0] - Position.deltaX;
- pos[1] += r[1] - Position.deltaY;
- }
-
- var d = this.currentDelta();
- pos[0] -= d[0];
- pos[1] -= d[1];
-
- if ( this.options.scroll && (this.options.scroll != window && this._isScrollChild) )
- {
- pos[0] -= this.options.scroll.scrollLeft - this.originalScrollLeft;
- pos[1] -= this.options.scroll.scrollTop - this.originalScrollTop;
- }
-
- var p = [0,1].map(function( i )
- {
- return (point[i] - pos[i] - this.offset[i])
- }.bind(this));
-
- if ( this.options.snap )
- {
- if ( typeof this.options.snap == 'function' )
- {
- p = this.options.snap(p[0], p[1], this);
- }
- else
- {
- if ( this.options.snap instanceof Array )
- {
- p = p.map(function( v, i )
- {
- return Math.round(v / this.options.snap[i]) * this.options.snap[i]
- }.bind(this))
- }
- else
- {
- p = p.map(function( v )
- {
- return Math.round(v / this.options.snap) * this.options.snap
- }.bind(this))
- }
- }
- }
-
- var style = this.element.style;
- if ( (!this.options.constraint) || (this.options.constraint == 'horizontal') )
- style.left = p[0] + "px";
- if ( (!this.options.constraint) || (this.options.constraint == 'vertical') )
- style.top = p[1] + "px";
-
- if ( style.visibility == "hidden" ) style.visibility = ""; // fix gecko rendering
- },
-
- stopScrolling: function()
- {
- if ( this.scrollInterval )
- {
- clearInterval(this.scrollInterval);
- this.scrollInterval = null;
- Draggables._lastScrollPointer = null;
- }
- },
-
- startScrolling: function( speed )
- {
- if ( !(speed[0] || speed[1]) ) return;
- this.scrollSpeed = [speed[0] * this.options.scrollSpeed,speed[1] * this.options.scrollSpeed];
- this.lastScrolled = new Date();
- this.scrollInterval = setInterval(this.scroll.bind(this), 10);
- },
-
- scroll: function()
- {
- var current = new Date();
- var delta = current - this.lastScrolled;
- this.lastScrolled = current;
- if ( this.options.scroll == window )
- {
- with ( this._getWindowScroll(this.options.scroll) )
- {
- if ( this.scrollSpeed[0] || this.scrollSpeed[1] )
- {
- var d = delta / 1000;
- this.options.scroll.scrollTo(left + d * this.scrollSpeed[0], top + d * this.scrollSpeed[1]);
- }
- }
- }
- else
- {
- this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
- this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
- }
-
- Position.prepare();
- Droppables.show(Draggables._lastPointer, this.element);
- Draggables.notify('onDrag', this);
- if ( this._isScrollChild )
- {
- Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
- Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
- Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
- if ( Draggables._lastScrollPointer[0] < 0 )
- Draggables._lastScrollPointer[0] = 0;
- if ( Draggables._lastScrollPointer[1] < 0 )
- Draggables._lastScrollPointer[1] = 0;
- this.draw(Draggables._lastScrollPointer);
- }
-
- if ( this.options.change ) this.options.change(this);
- },
-
- _getWindowScroll: function( w )
- {
- var T, L, W, H;
- with ( w.document )
- {
- if ( w.document.documentElement && documentElement.scrollTop )
- {
- T = documentElement.scrollTop;
- L = documentElement.scrollLeft;
- }
- else if ( w.document.body )
- {
- T = body.scrollTop;
- L = body.scrollLeft;
- }
- if ( w.innerWidth )
- {
- W = w.innerWidth;
- H = w.innerHeight;
- }
- else if ( w.document.documentElement && documentElement.clientWidth )
- {
- W = documentElement.clientWidth;
- H = documentElement.clientHeight;
- }
- else
- {
- W = body.offsetWidth;
- H = body.offsetHeight
- }
- }
- return { top: T, left: L, width: W, height: H };
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var SortableObserver = Class.create();
-SortableObserver.prototype = {
- initialize: function( element, observer )
- {
- this.element = $(element);
- this.observer = observer;
- this.lastValue = Sortable.serialize(this.element);
- },
-
- onStart: function()
- {
- this.lastValue = Sortable.serialize(this.element);
- },
-
- onEnd: function()
- {
- Sortable.unmark();
- if ( this.lastValue != Sortable.serialize(this.element) )
- this.observer(this.element)
- }
-}
-
-var Sortable = {
- SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
-
- sortables: {},
-
- _findRootElement: function( element )
- {
- while ( element.tagName != "BODY" )
- {
- if ( element.id && Sortable.sortables[element.id] ) return element;
- element = element.parentNode;
- }
- },
-
- options: function( element )
- {
- element = Sortable._findRootElement($(element));
- if ( !element ) return;
- return Sortable.sortables[element.id];
- },
-
- destroy: function( element )
- {
- var s = Sortable.options(element);
-
- if ( s )
- {
- Draggables.removeObserver(s.element);
- s.droppables.each(function( d )
- {
- Droppables.remove(d)
- });
- s.draggables.invoke('destroy');
-
- delete Sortable.sortables[s.element.id];
- }
- },
-
- create: function( element )
- {
- element = $(element);
- var options = Object.extend({
- element: element,
- tag: 'li', // assumes li children, override with tag: 'tagname'
- dropOnEmpty: false,
- tree: false,
- treeTag: 'ul',
- overlap: 'vertical', // one of 'vertical', 'horizontal'
- constraint: 'vertical', // one of 'vertical', 'horizontal', false
- containment: element, // also takes array of elements (or id's); or false
- handle: false, // or a CSS class
- only: false,
- delay: 0,
- hoverclass: null,
- ghosting: false,
- scroll: false,
- scrollSensitivity: 20,
- scrollSpeed: 15,
- format: this.SERIALIZE_RULE,
- onChange: Prototype.emptyFunction,
- onUpdate: Prototype.emptyFunction
- }, arguments[1] || {});
-
- // clear any old sortable with same element
- this.destroy(element);
-
- // build options for the draggables
- var options_for_draggable = {
- revert: true,
- scroll: options.scroll,
- scrollSpeed: options.scrollSpeed,
- scrollSensitivity: options.scrollSensitivity,
- delay: options.delay,
- ghosting: options.ghosting,
- constraint: options.constraint,
- handle: options.handle };
-
- if ( options.starteffect )
- options_for_draggable.starteffect = options.starteffect;
-
- if ( options.reverteffect )
- options_for_draggable.reverteffect = options.reverteffect;
- else
- if ( options.ghosting ) options_for_draggable.reverteffect = function( element )
- {
- element.style.top = 0;
- element.style.left = 0;
- };
-
- if ( options.endeffect )
- options_for_draggable.endeffect = options.endeffect;
-
- if ( options.zindex )
- options_for_draggable.zindex = options.zindex;
-
- // build options for the droppables
- var options_for_droppable = {
- overlap: options.overlap,
- containment: options.containment,
- tree: options.tree,
- hoverclass: options.hoverclass,
- onHover: Sortable.onHover
- //greedy: !options.dropOnEmpty
- }
-
- var options_for_tree = {
- onHover: Sortable.onEmptyHover,
- overlap: options.overlap,
- containment: options.containment,
- hoverclass: options.hoverclass
- }
-
- // fix for gecko engine
- Element.cleanWhitespace(element);
-
- options.draggables = [];
- options.droppables = [];
-
- // drop on empty handling
- if ( options.dropOnEmpty || options.tree )
- {
- Droppables.add(element, options_for_tree);
- options.droppables.push(element);
- }
-
- (this.findElements(element, options) || []).each(function( e )
- {
- // handles are per-draggable
- var handle = options.handle ? Element.childrenWithClassName(e, options.handle)[0] : e;
- options.draggables.push(new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
- Droppables.add(e, options_for_droppable);
- if ( options.tree ) e.treeNode = element;
- options.droppables.push(e);
- });
-
- if ( options.tree )
- {
- (Sortable.findTreeElements(element, options) || []).each(function( e )
- {
- Droppables.add(e, options_for_tree);
- e.treeNode = element;
- options.droppables.push(e);
- });
- }
-
- // keep reference
- this.sortables[element.id] = options;
-
- // for onupdate
- Draggables.addObserver(new SortableObserver(element, options.onUpdate));
-
- },
-
-// return all suitable-for-sortable elements in a guaranteed order
- findElements: function( element, options )
- {
- return Element.findChildren(element, options.only, options.tree ? true : false, options.tag);
- },
-
- findTreeElements: function( element, options )
- {
- return Element.findChildren(element, options.only, options.tree ? true : false, options.treeTag);
- },
-
- onHover: function( element, dropon, overlap )
- {
- if ( Element.isParent(dropon, element) ) return;
-
- if ( overlap > .33 && overlap < .66 && Sortable.options(dropon).tree )
- {
- return;
- }
- else if ( overlap > 0.5 )
- {
- Sortable.mark(dropon, 'before');
- if ( dropon.previousSibling != element )
- {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden";
- // fix gecko rendering
- dropon.parentNode.insertBefore(element, dropon);
- if ( dropon.parentNode != oldParentNode )
- Sortable.options(oldParentNode).onChange(element);
- Sortable.options(dropon.parentNode).onChange(element);
- }
- }
- else
- {
- Sortable.mark(dropon, 'after');
- var nextElement = dropon.nextSibling || null;
- if ( nextElement != element )
- {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden";
- // fix gecko rendering
- dropon.parentNode.insertBefore(element, nextElement);
- if ( dropon.parentNode != oldParentNode )
- Sortable.options(oldParentNode).onChange(element);
- Sortable.options(dropon.parentNode).onChange(element);
- }
- }
- },
-
- onEmptyHover: function( element, dropon, overlap )
- {
- var oldParentNode = element.parentNode;
- var droponOptions = Sortable.options(dropon);
-
- if ( !Element.isParent(dropon, element) )
- {
- var index;
-
- var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
- var child = null;
-
- if ( children )
- {
- var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
-
- for ( index = 0; index < children.length; index += 1 )
- {
- if ( offset - Element.offsetSize(children[index], droponOptions.overlap) >= 0 )
- {
- offset -= Element.offsetSize(children[index], droponOptions.overlap);
- }
- else if ( offset - (Element.offsetSize(children[index], droponOptions.overlap) / 2) >= 0 )
- {
- child = index + 1 < children.length ? children[index + 1] : null;
- break;
- }
- else
- {
- child = children[index];
- break;
- }
- }
- }
-
- dropon.insertBefore(element, child);
-
- Sortable.options(oldParentNode).onChange(element);
- droponOptions.onChange(element);
- }
- },
-
- unmark: function()
- {
- if ( Sortable._marker ) Element.hide(Sortable._marker);
- },
-
- mark: function( dropon, position )
- {
- // mark on ghosting only
- var sortable = Sortable.options(dropon.parentNode);
- if ( sortable && !sortable.ghosting ) return;
-
- if ( !Sortable._marker )
- {
- Sortable._marker = $('dropmarker') || document.createElement('DIV');
- Element.hide(Sortable._marker);
- Element.addClassName(Sortable._marker, 'dropmarker');
- Sortable._marker.style.position = 'absolute';
- document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
- }
- var offsets = Position.cumulativeOffset(dropon);
- Sortable._marker.style.left = offsets[0] + 'px';
- Sortable._marker.style.top = offsets[1] + 'px';
-
- if ( position == 'after' )
- if ( sortable.overlap == 'horizontal' )
- Sortable._marker.style.left = (offsets[0] + dropon.clientWidth) + 'px';
- else
- Sortable._marker.style.top = (offsets[1] + dropon.clientHeight) + 'px';
-
- Element.show(Sortable._marker);
- },
-
- _tree: function( element, options, parent )
- {
- var children = Sortable.findElements(element, options) || [];
-
- for ( var i = 0; i < children.length; ++i )
- {
- var match = children[i].id.match(options.format);
-
- if ( !match ) continue;
-
- var child = {
- id: encodeURIComponent(match ? match[1] : null),
- element: element,
- parent: parent,
- children: new Array,
- position: parent.children.length,
- container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase())
- }
-
- /* Get the element containing the children and recurse over it */
- if ( child.container )
- this._tree(child.container, options, child)
-
- parent.children.push(child);
- }
-
- return parent;
- },
-
-/* Finds the first element of the given tag type within a parent element.
-Used for finding the first LI[ST] within a L[IST]I[TEM].*/
- _findChildrenElement: function ( element, containerTag )
- {
- if ( element && element.hasChildNodes )
- for ( var i = 0; i < element.childNodes.length; ++i )
- if ( element.childNodes[i].tagName == containerTag )
- return element.childNodes[i];
-
- return null;
- },
-
- tree: function( element )
- {
- element = $(element);
- var sortableOptions = this.options(element);
- var options = Object.extend({
- tag: sortableOptions.tag,
- treeTag: sortableOptions.treeTag,
- only: sortableOptions.only,
- name: element.id,
- format: sortableOptions.format
- }, arguments[1] || {});
-
- var root = {
- id: null,
- parent: null,
- children: new Array,
- container: element,
- position: 0
- }
-
- return Sortable._tree(element, options, root);
- },
-
-/* Construct a [i] index for a particular node */
- _constructIndex: function( node )
- {
- var index = '';
- do {
- if ( node.id ) index = '[' + node.position + ']' + index;
- }
- while ( (node = node.parent) != null );
- return index;
- },
-
- sequence: function( element )
- {
- element = $(element);
- var options = Object.extend(this.options(element), arguments[1] || {});
-
- return $(this.findElements(element, options) || []).map(function( item )
- {
- return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
- });
- },
-
- setSequence: function( element, new_sequence )
- {
- element = $(element);
- var options = Object.extend(this.options(element), arguments[2] || {});
-
- var nodeMap = {};
- this.findElements(element, options).each(function( n )
- {
- if ( n.id.match(options.format) )
- nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
- n.parentNode.removeChild(n);
- });
-
- new_sequence.each(function( ident )
- {
- var n = nodeMap[ident];
- if ( n )
- {
- n[1].appendChild(n[0]);
- delete nodeMap[ident];
- }
- });
- },
-
- serialize: function( element )
- {
- element = $(element);
- var options = Object.extend(Sortable.options(element), arguments[1] || {});
- var name = encodeURIComponent((arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
-
- if ( options.tree )
- {
- return Sortable.tree(element, arguments[1]).children.map(function ( item )
- {
- return [name + Sortable._constructIndex(item) + "[id]=" +
- encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
- }).flatten().join('&');
- }
- else
- {
- return Sortable.sequence(element, arguments[1]).map(function( item )
- {
- return name + "[]=" + encodeURIComponent(item);
- }).join('&');
- }
- }
-}
-
-/* Returns true if child is contained within element */
-Element.isParent = function( child, element )
-{
- if ( !child.parentNode || child == element ) return false;
-
- if ( child.parentNode == element ) return true;
-
- return Element.isParent(child.parentNode, element);
-}
-
-Element.findChildren = function( element, only, recursive, tagName )
-{
- if ( !element.hasChildNodes() ) return null;
- tagName = tagName.toUpperCase();
- if ( only ) only = [only].flatten();
- var elements = [];
- $A(element.childNodes).each(function( e )
- {
- if ( e.tagName && e.tagName.toUpperCase() == tagName && (!only || (Element.classNames(e).detect(function( v )
- {
- return only.include(v)
- }))) )
- elements.push(e);
- if ( recursive )
- {
- var grandchildren = Element.findChildren(e, only, recursive, tagName);
- if ( grandchildren ) elements.push(grandchildren);
- }
- });
-
- return (elements.length > 0 ? elements.flatten() : []);
-}
-
-Element.offsetSize = function ( element, type )
-{
- if ( type == 'vertical' || type == 'height' )
- return element.offsetHeight;
- else
- return element.offsetWidth;
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-// script.aculo.us effects.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
-
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// Contributors:
-// Justin Palmer (http://encytemedia.com/)
-// Mark Pilgrim (http://diveintomark.org/)
-// Martin Bialasinki
-//
-// See scriptaculous.js for full license.
-
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function()
-{
- var color = '#';
- if ( this.slice(0, 4) == 'rgb(' )
- {
- var cols = this.slice(4, this.length - 1).split(',');
- var i = 0;
- do {
- color += parseInt(cols[i]).toColorPart()
- }
- while ( ++i < 3 );
- }
- else
- {
- if ( this.slice(0, 1) == '#' )
- {
- if ( this.length == 4 ) for ( var i = 1; i < 4; i++ ) color +=
- (this.charAt(i) + this.charAt(i)).toLowerCase();
- if ( this.length == 7 ) color = this.toLowerCase();
- }
- }
- return(color.length == 7 ? color : (arguments[0] || this));
-}
-
-/*--------------------------------------------------------------------------*/
-
-Element.collectTextNodes = function( element )
-{
- return $A($(element).childNodes).collect(function( node )
- {
- return (node.nodeType == 3 ? node.nodeValue : (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
- }).flatten().join('');
-}
-
-Element.collectTextNodesIgnoreClass = function( element, className )
-{
- return $A($(element).childNodes).collect(function( node )
- {
- return (node.nodeType == 3 ? node.nodeValue : ((node.hasChildNodes() && !Element.hasClassName(node, className))
- ? Element.collectTextNodesIgnoreClass(node, className) : ''));
- }).flatten().join('');
-}
-
-Element.setContentZoom = function( element, percent )
-{
- element = $(element);
- Element.setStyle(element, {fontSize: (percent / 100) + 'em'});
- if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) window.scrollBy(0, 0);
-}
-
-Element.getOpacity = function( element )
-{
- var opacity;
- if ( opacity = Element.getStyle(element, 'opacity') )
- return parseFloat(opacity);
- if ( opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/) )
- if ( opacity[1] ) return parseFloat(opacity[1]) / 100;
- return 1.0;
-}
-
-Element.setOpacity = function( element, value )
-{
- element = $(element);
- if ( value == 1 )
- {
- Element.setStyle(element, { opacity:
- (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999
- : 1.0 });
- if ( /MSIE/.test(navigator.userAgent) && !window.opera )
- Element.setStyle(element, {filter: Element.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '')});
- }
- else
- {
- if ( value < 0.00001 ) value = 0;
- Element.setStyle(element, {opacity: value});
- if ( /MSIE/.test(navigator.userAgent) && !window.opera )
- Element.setStyle(element, { filter: Element.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '') +
- 'alpha(opacity=' + value * 100 + ')' });
- }
-}
-
-Element.getInlineOpacity = function( element )
-{
- return $(element).style.opacity || '';
-}
-
-Element.childrenWithClassName = function( element, className, findFirst )
-{
- var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
- var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select'](function( c )
- {
- return (c.className && c.className.match(classNameRegExp));
- });
- if ( !results ) results = [];
- return results;
-}
-
-Element.forceRerendering = function( element )
-{
- try
- {
- element = $(element);
- var n = document.createTextNode(' ');
- element.appendChild(n);
- element.removeChild(n);
- }
- catch( e )
- {
- }
-};
-
-/*--------------------------------------------------------------------------*/
-
-Array.prototype.call = function()
-{
- var args = arguments;
- this.each(function( f )
- {
- f.apply(this, args)
- });
-}
-
-/*--------------------------------------------------------------------------*/
-
-var Effect = {
- _elementDoesNotExistError: {
- name: 'ElementDoesNotExistError',
- message: 'The specified DOM element does not exist, but is required for this effect to operate'
- },
- tagifyText: function( element )
- {
- if ( typeof Builder == 'undefined' )
- throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
-
- var tagifyStyle = 'position:relative';
- if ( /MSIE/.test(navigator.userAgent) && !window.opera ) tagifyStyle += ';zoom:1';
- element = $(element);
- $A(element.childNodes).each(function( child )
- {
- if ( child.nodeType == 3 )
- {
- child.nodeValue.toArray().each(function( character )
- {
- element.insertBefore(Builder.node('span', {style: tagifyStyle}, character == ' '
- ? String.fromCharCode(160) : character), child);
- });
- Element.remove(child);
- }
- });
- },
- multiple: function( element, effect )
- {
- var elements;
- if ( ((typeof element == 'object') || (typeof element == 'function')) && (element.length) )
- elements = element;
- else
- elements = $(element).childNodes;
-
- var options = Object.extend({
- speed: 0.1,
- delay: 0.0
- }, arguments[2] || {});
- var masterDelay = options.delay;
-
- $A(elements).each(function( element, index )
- {
- new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
- });
- },
- PAIRS: {
- 'slide': ['SlideDown','SlideUp'],
- 'blind': ['BlindDown','BlindUp'],
- 'appear': ['Appear','Fade']
- },
- toggle: function( element, effect )
- {
- element = $(element);
- effect = (effect || 'appear').toLowerCase();
- var options = Object.extend({
- queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
- }, arguments[2] || {});
- Effect[element.visible() ? Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
- }
-};
-
-var Effect2 = Effect;
-// deprecated
-
-/* ------------- transitions ------------- */
-
-Effect.Transitions = {}
-
-Effect.Transitions.linear = Prototype.K;
-
-Effect.Transitions.sinoidal = function( pos )
-{
- return (-Math.cos(pos * Math.PI) / 2) + 0.5;
-}
-Effect.Transitions.reverse = function( pos )
-{
- return 1 - pos;
-}
-Effect.Transitions.flicker = function( pos )
-{
- return ((-Math.cos(pos * Math.PI) / 4) + 0.75) + Math.random() / 4;
-}
-Effect.Transitions.wobble = function( pos )
-{
- return (-Math.cos(pos * Math.PI * (9 * pos)) / 2) + 0.5;
-}
-Effect.Transitions.pulse = function( pos )
-{
- return (Math.floor(pos * 10) % 2 == 0 ? (pos * 10 - Math.floor(pos * 10)) : 1 - (pos * 10 - Math.floor(pos * 10)));
-}
-Effect.Transitions.none = function( pos )
-{
- return 0;
-}
-Effect.Transitions.full = function( pos )
-{
- return 1;
-}
-
-/* ------------- core effects ------------- */
-
-Effect.ScopedQueue = Class.create();
-Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
- initialize: function()
- {
- this.effects = [];
- this.interval = null;
- },
- _each: function( iterator )
- {
- this.effects._each(iterator);
- },
- add: function( effect )
- {
- var timestamp = new Date().getTime();
-
- var position = (typeof effect.options.queue == 'string') ? effect.options.queue : effect.options.queue.position;
-
- switch ( position )
- {
- case 'front':
- // move unstarted effects after this effect
- this.effects.findAll(function( e )
- {
- return e.state == 'idle'
- }).each(function( e )
- {
- e.startOn += effect.finishOn;
- e.finishOn += effect.finishOn;
- });
- break;
- case 'end':
- // start effect after last queued effect has finished
- timestamp = this.effects.pluck('finishOn').max() || timestamp;
- break;
- }
-
- effect.startOn += timestamp;
- effect.finishOn += timestamp;
-
- if ( !effect.options.queue.limit || (this.effects.length < effect.options.queue.limit) )
- this.effects.push(effect);
-
- if ( !this.interval )
- this.interval = setInterval(this.loop.bind(this), 40);
- },
- remove: function( effect )
- {
- this.effects = this.effects.reject(function( e )
- {
- return e == effect
- });
- if ( this.effects.length == 0 )
- {
- clearInterval(this.interval);
- this.interval = null;
- }
- },
- loop: function()
- {
- var timePos = new Date().getTime();
- this.effects.invoke('loop', timePos);
- }
-});
-
-Effect.Queues = {
- instances: $H(),
- get: function( queueName )
- {
- if ( typeof queueName != 'string' ) return queueName;
-
- if ( !this.instances[queueName] )
- this.instances[queueName] = new Effect.ScopedQueue();
-
- return this.instances[queueName];
- }
-}
-Effect.Queue = Effect.Queues.get('global');
-
-Effect.DefaultOptions = {
- transition: Effect.Transitions.sinoidal,
- duration: 1.0, // seconds
- fps: 25.0, // max. 25fps due to Effect.Queue implementation
- sync: false, // true for combining
- from: 0.0,
- to: 1.0,
- delay: 0.0,
- queue: 'parallel'
-}
-
-Effect.Base = function()
-{
-};
-Effect.Base.prototype = {
- position: null,
- start: function( options )
- {
- this.options = Object.extend(Object.extend({}, Effect.DefaultOptions), options || {});
- this.currentFrame = 0;
- this.state = 'idle';
- this.startOn = this.options.delay * 1000;
- this.finishOn = this.startOn + (this.options.duration * 1000);
- this.event('beforeStart');
- if ( !this.options.sync )
- Effect.Queues.get(typeof this.options.queue == 'string' ? 'global' : this.options.queue.scope).add(this);
- },
- loop: function( timePos )
- {
- if ( timePos >= this.startOn )
- {
- if ( timePos >= this.finishOn )
- {
- this.render(1.0);
- this.cancel();
- this.event('beforeFinish');
- if ( this.finish ) this.finish();
- this.event('afterFinish');
- return;
- }
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
- var frame = Math.round(pos * this.options.fps * this.options.duration);
- if ( frame > this.currentFrame )
- {
- this.render(pos);
- this.currentFrame = frame;
- }
- }
- },
- render: function( pos )
- {
- if ( this.state == 'idle' )
- {
- this.state = 'running';
- this.event('beforeSetup');
- if ( this.setup ) this.setup();
- this.event('afterSetup');
- }
- if ( this.state == 'running' )
- {
- if ( this.options.transition ) pos = this.options.transition(pos);
- pos *= (this.options.to - this.options.from);
- pos += this.options.from;
- this.position = pos;
- this.event('beforeUpdate');
- if ( this.update ) this.update(pos);
- this.event('afterUpdate');
- }
- },
- cancel: function()
- {
- if ( !this.options.sync )
- Effect.Queues.get(typeof this.options.queue == 'string' ? 'global' : this.options.queue.scope).remove(this);
- this.state = 'finished';
- },
- event: function( eventName )
- {
- if ( this.options[eventName + 'Internal'] ) this.options[eventName + 'Internal'](this);
- if ( this.options[eventName] ) this.options[eventName](this);
- },
- inspect: function()
- {
- return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
- }
-}
-
-Effect.Parallel = Class.create();
-Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
- initialize: function( effects )
- {
- this.effects = effects || [];
- this.start(arguments[1]);
- },
- update: function( position )
- {
- this.effects.invoke('render', position);
- },
- finish: function( position )
- {
- this.effects.each(function( effect )
- {
- effect.render(1.0);
- effect.cancel();
- effect.event('beforeFinish');
- if ( effect.finish ) effect.finish(position);
- effect.event('afterFinish');
- });
- }
-});
-
-Effect.Opacity = Class.create();
-Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
- initialize: function( element )
- {
- this.element = $(element);
- if ( !this.element ) throw(Effect._elementDoesNotExistError);
- // make this work on IE on elements without 'layout'
- if ( /MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout) )
- this.element.setStyle({zoom: 1});
- var options = Object.extend({
- from: this.element.getOpacity() || 0.0,
- to: 1.0
- }, arguments[1] || {});
- this.start(options);
- },
- update: function( position )
- {
- this.element.setOpacity(position);
- }
-});
-
-Effect.Move = Class.create();
-Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
- initialize: function( element )
- {
- this.element = $(element);
- if ( !this.element ) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({
- x: 0,
- y: 0,
- mode: 'relative'
- }, arguments[1] || {});
- this.start(options);
- },
- setup: function()
- {
- // Bug in Opera: Opera returns the "real" position of a static element or
- // relative element that does not have top/left explicitly set.
- // ==> Always set top and left for position relative elements in your stylesheets
- // (to 0 if you do not need them)
- this.element.makePositioned();
- this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
- this.originalTop = parseFloat(this.element.getStyle('top') || '0');
- if ( this.options.mode == 'absolute' )
- {
- // absolute movement, so we need to calc deltaX and deltaY
- this.options.x = this.options.x - this.originalLeft;
- this.options.y = this.options.y - this.originalTop;
- }
- },
- update: function( position )
- {
- this.element.setStyle({
- left: Math.round(this.options.x * position + this.originalLeft) + 'px',
- top: Math.round(this.options.y * position + this.originalTop) + 'px'
- });
- }
-});
-
-// for backwards compatibility
-Effect.MoveBy = function( element, toTop, toLeft )
-{
- return new Effect.Move(element, Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
-};
-
-Effect.Scale = Class.create();
-Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
- initialize: function( element, percent )
- {
- this.element = $(element);
- if ( !this.element ) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({
- scaleX: true,
- scaleY: true,
- scaleContent: true,
- scaleFromCenter: false,
- scaleMode: 'box', // 'box' or 'contents' or {} with provided values
- scaleFrom: 100.0,
- scaleTo: percent
- }, arguments[2] || {});
- this.start(options);
- },
- setup: function()
- {
- this.restoreAfterFinish = this.options.restoreAfterFinish || false;
- this.elementPositioning = this.element.getStyle('position');
-
- this.originalStyle = {};
- ['top','left','width','height','fontSize'].each(function( k )
- {
- this.originalStyle[k] = this.element.style[k];
- }.bind(this));
-
- this.originalTop = this.element.offsetTop;
- this.originalLeft = this.element.offsetLeft;
-
- var fontSize = this.element.getStyle('font-size') || '100%';
- ['em','px','%','pt'].each(function( fontSizeType )
- {
- if ( fontSize.indexOf(fontSizeType) > 0 )
- {
- this.fontSize = parseFloat(fontSize);
- this.fontSizeType = fontSizeType;
- }
- }.bind(this));
-
- this.factor = (this.options.scaleTo - this.options.scaleFrom) / 100;
-
- this.dims = null;
- if ( this.options.scaleMode == 'box' )
- this.dims = [this.element.offsetHeight, this.element.offsetWidth];
- if ( /^content/.test(this.options.scaleMode) )
- this.dims = [this.element.scrollHeight, this.element.scrollWidth];
- if ( !this.dims )
- this.dims = [this.options.scaleMode.originalHeight,
- this.options.scaleMode.originalWidth];
- },
- update: function( position )
- {
- var currentScale = (this.options.scaleFrom / 100.0) + (this.factor * position);
- if ( this.options.scaleContent && this.fontSize )
- this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
- this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
- },
- finish: function( position )
- {
- if ( this.restoreAfterFinish ) this.element.setStyle(this.originalStyle);
- },
- setDimensions: function( height, width )
- {
- var d = {};
- if ( this.options.scaleX ) d.width = Math.round(width) + 'px';
- if ( this.options.scaleY ) d.height = Math.round(height) + 'px';
- if ( this.options.scaleFromCenter )
- {
- var topd = (height - this.dims[0]) / 2;
- var leftd = (width - this.dims[1]) / 2;
- if ( this.elementPositioning == 'absolute' )
- {
- if ( this.options.scaleY ) d.top = this.originalTop - topd + 'px';
- if ( this.options.scaleX ) d.left = this.originalLeft - leftd + 'px';
- }
- else
- {
- if ( this.options.scaleY ) d.top = -topd + 'px';
- if ( this.options.scaleX ) d.left = -leftd + 'px';
- }
- }
- this.element.setStyle(d);
- }
-});
-
-Effect.Highlight = Class.create();
-Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
- initialize: function( element )
- {
- this.element = $(element);
- if ( !this.element ) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
- this.start(options);
- },
- setup: function()
- {
- // Prevent executing on elements not in the layout flow
- if ( this.element.getStyle('display') == 'none' )
- {
- this.cancel();
- return;
- }
- // Disable background image during the effect
- this.oldStyle = {
- backgroundImage: this.element.getStyle('background-image') };
- this.element.setStyle({backgroundImage: 'none'});
- if ( !this.options.endcolor )
- this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
- if ( !this.options.restorecolor )
- this.options.restorecolor = this.element.getStyle('background-color');
- // init color calculations
- this._base = $R(0, 2).map(function( i )
- {
- return parseInt(this.options.startcolor.slice(i * 2 + 1, i * 2 + 3), 16)
- }.bind(this));
- this._delta = $R(0, 2).map(function( i )
- {
- return parseInt(this.options.endcolor.slice(i * 2 + 1, i * 2 + 3), 16) - this._base[i]
- }.bind(this));
- },
- update: function( position )
- {
- this.element.setStyle({backgroundColor: $R(0, 2).inject('#', function( m, v, i )
- {
- return m + (Math.round(this._base[i] + (this._delta[i] * position)).toColorPart());
- }.bind(this)) });
- },
- finish: function()
- {
- this.element.setStyle(Object.extend(this.oldStyle, {
- backgroundColor: this.options.restorecolor
- }));
- }
-});
-
-Effect.ScrollTo = Class.create();
-Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
- initialize: function( element )
- {
- this.element = $(element);
- this.start(arguments[1] || {});
- },
- setup: function()
- {
- Position.prepare();
- var offsets = Position.cumulativeOffset(this.element);
- if ( this.options.offset ) offsets[1] += this.options.offset;
- var max = window.innerHeight ? window.height - window.innerHeight : document.body.scrollHeight -
- (document.documentElement.clientHeight
- ? document.documentElement.clientHeight
- : document.body.clientHeight);
- this.scrollStart = Position.deltaY;
- this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
- },
- update: function( position )
- {
- Position.prepare();
- window.scrollTo(Position.deltaX, this.scrollStart + (position * this.delta));
- }
-});
-
-/* ------------- combination effects ------------- */
-
-Effect.Fade = function( element )
-{
- element = $(element);
- var oldOpacity = element.getInlineOpacity();
- var options = Object.extend({
- from: element.getOpacity() || 1.0,
- to: 0.0,
- afterFinishInternal: function( effect )
- {
- if ( effect.options.to != 0 ) return;
- effect.element.hide();
- effect.element.setStyle({opacity: oldOpacity});
- }}, arguments[1] || {});
- return new Effect.Opacity(element, options);
-}
-
-Effect.Appear = function( element )
-{
- element = $(element);
- var options = Object.extend({
- from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
- to: 1.0,
- // force Safari to render floated elements properly
- afterFinishInternal: function( effect )
- {
- effect.element.forceRerendering();
- },
- beforeSetup: function( effect )
- {
- effect.element.setOpacity(effect.options.from);
- effect.element.show();
- }}, arguments[1] || {});
- return new Effect.Opacity(element, options);
-}
-
-Effect.Puff = function( element )
-{
- element = $(element);
- var oldStyle = {
- opacity: element.getInlineOpacity(),
- position: element.getStyle('position'),
- top: element.style.top,
- left: element.style.left,
- width: element.style.width,
- height: element.style.height
- };
- return new Effect.Parallel([ new Effect.Scale(element, 200, { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
- new Effect.Opacity(element, { sync: true, to: 0.0 }) ], Object.extend({ duration: 1.0,
- beforeSetupInternal: function( effect )
- {
- Position.absolutize(effect.effects[0].element)
- },
- afterFinishInternal: function( effect )
- {
- effect.effects[0].element.hide();
- effect.effects[0].element.setStyle(oldStyle);
- }
- }, arguments[1] || {}));
-}
-
-Effect.BlindUp = function( element )
-{
- element = $(element);
- element.makeClipping();
- return new Effect.Scale(element, 0, Object.extend({ scaleContent: false,
- scaleX: false,
- restoreAfterFinish: true,
- afterFinishInternal: function( effect )
- {
- effect.element.hide();
- effect.element.undoClipping();
- }
- }, arguments[1] || {}));
-}
-
-Effect.BlindDown = function( element )
-{
- element = $(element);
- var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
- scaleX: false,
- scaleFrom: 0,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
- restoreAfterFinish: true,
- afterSetup: function( effect )
- {
- effect.element.makeClipping();
- effect.element.setStyle({height: '0px'});
- effect.element.show();
- },
- afterFinishInternal: function( effect )
- {
- effect.element.undoClipping();
- }
- }, arguments[1] || {}));
-}
-
-Effect.SwitchOff = function( element )
-{
- element = $(element);
- var oldOpacity = element.getInlineOpacity();
- return new Effect.Appear(element, Object.extend({
- duration: 0.4,
- from: 0,
- transition: Effect.Transitions.flicker,
- afterFinishInternal: function( effect )
- {
- new Effect.Scale(effect.element, 1, {
- duration: 0.3, scaleFromCenter: true,
- scaleX: false, scaleContent: false, restoreAfterFinish: true,
- beforeSetup: function( effect )
- {
- effect.element.makePositioned();
- effect.element.makeClipping();
- },
- afterFinishInternal: function( effect )
- {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.undoPositioned();
- effect.element.setStyle({opacity: oldOpacity});
- }
- })
- }
- }, arguments[1] || {}));
-}
-
-Effect.DropOut = function( element )
-{
- element = $(element);
- var oldStyle = {
- top: element.getStyle('top'),
- left: element.getStyle('left'),
- opacity: element.getInlineOpacity() };
- return new Effect.Parallel([ new Effect.Move(element, {x: 0, y: 100, sync: true }),
- new Effect.Opacity(element, { sync: true, to: 0.0 }) ], Object.extend({ duration: 0.5,
- beforeSetup: function( effect )
- {
- effect.effects[0].element.makePositioned();
- },
- afterFinishInternal: function( effect )
- {
- effect.effects[0].element.hide();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle);
- }
- }, arguments[1] || {}));
-}
-
-Effect.Shake = function( element )
-{
- element = $(element);
- var oldStyle = {
- top: element.getStyle('top'),
- left: element.getStyle('left') };
- return new Effect.Move(element, { x: 20, y: 0, duration: 0.05, afterFinishInternal: function( effect )
- {
- new Effect.Move(effect.element, { x: -40, y: 0, duration: 0.1, afterFinishInternal: function( effect )
- {
- new Effect.Move(effect.element, { x: 40, y: 0, duration: 0.1, afterFinishInternal: function( effect )
- {
- new Effect.Move(effect.element, { x: -40, y: 0, duration: 0.1, afterFinishInternal: function( effect )
- {
- new Effect.Move(effect.element, { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(
- effect )
- {
- new Effect.Move(effect.element, { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(
- effect )
- {
- effect.element.undoPositioned();
- effect.element.setStyle(oldStyle);
- }})
- }})
- }})
- }})
- }})
- }});
-}
-
-Effect.SlideDown = function( element )
-{
- element = $(element);
- element.cleanWhitespace();
- // SlideDown need to have the content of the element wrapped in a container element with fixed height!
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
- var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
- scaleX: false,
- scaleFrom: window.opera ? 0 : 1,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
- restoreAfterFinish: true,
- afterSetup: function( effect )
- {
- effect.element.makePositioned();
- effect.element.firstChild.makePositioned();
- if ( window.opera ) effect.element.setStyle({top: ''});
- effect.element.makeClipping();
- effect.element.setStyle({height: '0px'});
- effect.element.show();
- },
- afterUpdateInternal: function( effect )
- {
- effect.element.firstChild.setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
- },
- afterFinishInternal: function( effect )
- {
- effect.element.undoClipping();
- // IE will crash if child is undoPositioned first
- if ( /MSIE/.test(navigator.userAgent) && !window.opera )
- {
- effect.element.undoPositioned();
- effect.element.firstChild.undoPositioned();
- }
- else
- {
- effect.element.firstChild.undoPositioned();
- effect.element.undoPositioned();
- }
- effect.element.firstChild.setStyle({bottom: oldInnerBottom});
- }
- }, arguments[1] || {}));
-}
-
-Effect.SlideUp = function( element )
-{
- element = $(element);
- element.cleanWhitespace();
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
- return new Effect.Scale(element, window.opera ? 0 : 1, Object.extend({ scaleContent: false,
- scaleX: false,
- scaleMode: 'box',
- scaleFrom: 100,
- restoreAfterFinish: true,
- beforeStartInternal: function( effect )
- {
- effect.element.makePositioned();
- effect.element.firstChild.makePositioned();
- if ( window.opera ) effect.element.setStyle({top: ''});
- effect.element.makeClipping();
- effect.element.show();
- },
- afterUpdateInternal: function( effect )
- {
- effect.element.firstChild.setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
- },
- afterFinishInternal: function( effect )
- {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.firstChild.undoPositioned();
- effect.element.undoPositioned();
- effect.element.setStyle({bottom: oldInnerBottom});
- }
- }, arguments[1] || {}));
-}
-
-// Bug in opera makes the TD containing this element expand for a instance after finish
-Effect.Squish = function( element )
-{
- return new Effect.Scale(element, window.opera ? 1 : 0, { restoreAfterFinish: true,
- beforeSetup: function( effect )
- {
- effect.element.makeClipping(effect.element);
- },
- afterFinishInternal: function( effect )
- {
- effect.element.hide(effect.element);
- effect.element.undoClipping(effect.element);
- }
- });
-}
-
-Effect.Grow = function( element )
-{
- element = $(element);
- var options = Object.extend({
- direction: 'center',
- moveTransition: Effect.Transitions.sinoidal,
- scaleTransition: Effect.Transitions.sinoidal,
- opacityTransition: Effect.Transitions.full
- }, arguments[1] || {});
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- height: element.style.height,
- width: element.style.width,
- opacity: element.getInlineOpacity() };
-
- var dims = element.getDimensions();
- var initialMoveX, initialMoveY;
- var moveX, moveY;
-
- switch ( options.direction )
- {
- case 'top-left':
- initialMoveX = initialMoveY = moveX = moveY = 0;
- break;
- case 'top-right':
- initialMoveX = dims.width;
- initialMoveY = moveY = 0;
- moveX = -dims.width;
- break;
- case 'bottom-left':
- initialMoveX = moveX = 0;
- initialMoveY = dims.height;
- moveY = -dims.height;
- break;
- case 'bottom-right':
- initialMoveX = dims.width;
- initialMoveY = dims.height;
- moveX = -dims.width;
- moveY = -dims.height;
- break;
- case 'center':
- initialMoveX = dims.width / 2;
- initialMoveY = dims.height / 2;
- moveX = -dims.width / 2;
- moveY = -dims.height / 2;
- break;
- }
-
- return new Effect.Move(element, {
- x: initialMoveX,
- y: initialMoveY,
- duration: 0.01,
- beforeSetup: function( effect )
- {
- effect.element.hide();
- effect.element.makeClipping();
- effect.element.makePositioned();
- },
- afterFinishInternal: function( effect )
- {
- new Effect.Parallel([ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
- new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
- new Effect.Scale(effect.element, 100, {
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
- sync: true, scaleFrom: window.opera ? 1
- : 0, transition: options.scaleTransition, restoreAfterFinish: true})
- ], Object.extend({
- beforeSetup: function( effect )
- {
- effect.effects[0].element.setStyle({height: '0px'});
- effect.effects[0].element.show();
- },
- afterFinishInternal: function( effect )
- {
- effect.effects[0].element.undoClipping();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle);
- }
- }, options))
- }
- });
-}
-
-Effect.Shrink = function( element )
-{
- element = $(element);
- var options = Object.extend({
- direction: 'center',
- moveTransition: Effect.Transitions.sinoidal,
- scaleTransition: Effect.Transitions.sinoidal,
- opacityTransition: Effect.Transitions.none
- }, arguments[1] || {});
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- height: element.style.height,
- width: element.style.width,
- opacity: element.getInlineOpacity() };
-
- var dims = element.getDimensions();
- var moveX, moveY;
-
- switch ( options.direction )
- {
- case 'top-left':
- moveX = moveY = 0;
- break;
- case 'top-right':
- moveX = dims.width;
- moveY = 0;
- break;
- case 'bottom-left':
- moveX = 0;
- moveY = dims.height;
- break;
- case 'bottom-right':
- moveX = dims.width;
- moveY = dims.height;
- break;
- case 'center':
- moveX = dims.width / 2;
- moveY = dims.height / 2;
- break;
- }
-
- return new Effect.Parallel([ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
- new Effect.Scale(element, window.opera ? 1
- : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
- new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
- ], Object.extend({
- beforeStartInternal: function( effect )
- {
- effect.effects[0].element.makePositioned();
- effect.effects[0].element.makeClipping();
- },
- afterFinishInternal: function( effect )
- {
- effect.effects[0].element.hide();
- effect.effects[0].element.undoClipping();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle);
- }
- }, options));
-}
-
-Effect.Pulsate = function( element )
-{
- element = $(element);
- var options = arguments[1] || {};
- var oldOpacity = element.getInlineOpacity();
- var transition = options.transition || Effect.Transitions.sinoidal;
- var reverser = function( pos )
- {
- return transition(1 - Effect.Transitions.pulse(pos))
- };
- reverser.bind(transition);
- return new Effect.Opacity(element, Object.extend(Object.extend({ duration: 3.0, from: 0,
- afterFinishInternal: function( effect )
- {
- effect.element.setStyle({opacity: oldOpacity});
- }
- }, options), {transition: reverser}));
-}
-
-Effect.Fold = function( element )
-{
- element = $(element);
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- width: element.style.width,
- height: element.style.height };
- Element.makeClipping(element);
- return new Effect.Scale(element, 5, Object.extend({
- scaleContent: false,
- scaleX: false,
- afterFinishInternal: function( effect )
- {
- new Effect.Scale(element, 1, {
- scaleContent: false,
- scaleY: false,
- afterFinishInternal: function( effect )
- {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.setStyle(oldStyle);
- } });
- }}, arguments[1] || {}));
-};
-
-['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
- 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(function( f )
-{
- Element.Methods[f] = Element[f];
-});
-
-Element.Methods.visualEffect = function( element, effect, options )
-{
- s = effect.gsub(/_/, '-').camelize();
- effect_class = s.charAt(0).toUpperCase() + s.substring(1);
- new Effect[effect_class](element, options);
- return $(element);
-};
-
-Element.addMethods();
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/* Prototype JavaScript framework, version 1.5.0_rc1
- * (c) 2005 Sam Stephenson <sam@conio.net>
- *
- * Prototype is freely distributable under the terms of an MIT-style license.
- * For details, see the Prototype web site: http://prototype.conio.net/
- *
-/*--------------------------------------------------------------------------*/
-
-var Prototype = {
- Version: '1.5.0_rc1',
- ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
-
- emptyFunction: function()
- {
- },
- K: function( x )
- {
- return x
- }
-}
-
-var Class = {
- create: function()
- {
- return function()
- {
- this.initialize.apply(this, arguments);
- }
- }
-}
-
-var Abstract = new Object();
-
-Object.extend = function( destination, source )
-{
- for ( var property in source )
- {
- destination[property] = source[property];
- }
- return destination;
-}
-
-Object.extend(Object, {
- inspect: function( object )
- {
- try
- {
- if ( object == undefined ) return 'undefined';
- if ( object == null ) return 'null';
- return object.inspect ? object.inspect() : object.toString();
- }
- catch ( e )
- {
- if ( e instanceof RangeError ) return '...';
- throw e;
- }
- },
-
- keys: function( object )
- {
- var keys = [];
- for ( var property in object )
- keys.push(property);
- return keys;
- },
-
- values: function( object )
- {
- var values = [];
- for ( var property in object )
- values.push(object[property]);
- return values;
- },
-
- clone: function( object )
- {
- return Object.extend({}, object);
- }
-});
-
-Function.prototype.bind = function()
-{
- var __method = this, args = $A(arguments), object = args.shift();
- return function()
- {
- return __method.apply(object, args.concat($A(arguments)));
- }
-}
-
-Function.prototype.bindAsEventListener = function( object )
-{
- var __method = this, args = $A(arguments), object = args.shift();
- return function( event )
- {
- return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
- }
-}
-
-Object.extend(Number.prototype, {
- toColorPart: function()
- {
- var digits = this.toString(16);
- if ( this < 16 ) return '0' + digits;
- return digits;
- },
-
- succ: function()
- {
- return this + 1;
- },
-
- times: function( iterator )
- {
- $R(0, this, true).each(iterator);
- return this;
- }
-});
-
-var Try = {
- these: function()
- {
- var returnValue;
-
- for ( var i = 0; i < arguments.length; i++ )
- {
- var lambda = arguments[i];
- try
- {
- returnValue = lambda();
- break;
- }
- catch ( e )
- {
- }
- }
-
- return returnValue;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var PeriodicalExecuter = Class.create();
-PeriodicalExecuter.prototype = {
- initialize: function( callback, frequency )
- {
- this.callback = callback;
- this.frequency = frequency;
- this.currentlyExecuting = false;
-
- this.registerCallback();
- },
-
- registerCallback: function()
- {
- this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- stop: function()
- {
- if ( !this.timer ) return;
- clearInterval(this.timer);
- this.timer = null;
- },
-
- onTimerEvent: function()
- {
- if ( !this.currentlyExecuting )
- {
- try
- {
- this.currentlyExecuting = true;
- this.callback(this);
- }
- finally
- {
- this.currentlyExecuting = false;
- }
- }
- }
-}
-Object.extend(String.prototype, {
- gsub: function( pattern, replacement )
- {
- var result = '', source = this, match;
- replacement = arguments.callee.prepareReplacement(replacement);
-
- while ( source.length > 0 )
- {
- if ( match = source.match(pattern) )
- {
- result += source.slice(0, match.index);
- result += (replacement(match) || '').toString();
- source = source.slice(match.index + match[0].length);
- }
- else
- {
- result += source,source = '';
- }
- }
- return result;
- },
-
- sub: function( pattern, replacement, count )
- {
- replacement = this.gsub.prepareReplacement(replacement);
- count = count === undefined ? 1 : count;
-
- return this.gsub(pattern, function( match )
- {
- if ( --count < 0 ) return match[0];
- return replacement(match);
- });
- },
-
- scan: function( pattern, iterator )
- {
- this.gsub(pattern, iterator);
- return this;
- },
-
- truncate: function( length, truncation )
- {
- length = length || 30;
- truncation = truncation === undefined ? '...' : truncation;
- return this.length > length ? this.slice(0, length - truncation.length) + truncation : this;
- },
-
- strip: function()
- {
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
- },
-
- stripTags: function()
- {
- return this.replace(/<\/?[^>]+>/gi, '');
- },
-
- stripScripts: function()
- {
- return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
- },
-
- extractScripts: function()
- {
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
- return (this.match(matchAll) || []).map(function( scriptTag )
- {
- return (scriptTag.match(matchOne) || ['', ''])[1];
- });
- },
-
- evalScripts: function()
- {
- return this.extractScripts().map(function( script )
- {
- return eval(script)
- });
- },
-
- escapeHTML: function()
- {
- var div = document.createElement('div');
- var text = document.createTextNode(this);
- div.appendChild(text);
- return div.innerHTML;
- },
-
- unescapeHTML: function()
- {
- var div = document.createElement('div');
- div.innerHTML = this.stripTags();
- return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
- },
-
- toQueryParams: function()
- {
- var pairs = this.match(/^\??(.*)$/)[1].split('&');
- return pairs.inject({}, function( params, pairString )
- {
- var pair = pairString.split('=');
- var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
- params[decodeURIComponent(pair[0])] = value;
- return params;
- });
- },
-
- toArray: function()
- {
- return this.split('');
- },
-
- camelize: function()
- {
- var oStringList = this.split('-');
- if ( oStringList.length == 1 ) return oStringList[0];
-
- var camelizedString = this.indexOf('-') == 0 ? oStringList[0].charAt(0).toUpperCase() +
- oStringList[0].substring(1) : oStringList[0];
-
- for ( var i = 1, len = oStringList.length; i < len; i++ )
- {
- var s = oStringList[i];
- camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
- }
-
- return camelizedString;
- },
-
- inspect: function( useDoubleQuotes )
- {
- var escapedString = this.replace(/\\/g, '\\\\');
- if ( useDoubleQuotes )
- return '"' + escapedString.replace(/"/g, '\\"') + '"';
- else
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
- }
-});
-
-String.prototype.gsub.prepareReplacement = function( replacement )
-{
- if ( typeof replacement == 'function' ) return replacement;
- var template = new Template(replacement);
- return function( match )
- {
- return template.evaluate(match)
- };
-}
-
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-var Template = Class.create();
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-Template.prototype = {
- initialize: function( template, pattern )
- {
- this.template = template.toString();
- this.pattern = pattern || Template.Pattern;
- },
-
- evaluate: function( object )
- {
- return this.template.gsub(this.pattern, function( match )
- {
- var before = match[1];
- if ( before == '\\' ) return match[2];
- return before + (object[match[3]] || '').toString();
- });
- }
-}
-
-var $break = new Object();
-var $continue = new Object();
-
-var Enumerable = {
- each: function( iterator )
- {
- var index = 0;
- try
- {
- this._each(function( value )
- {
- try
- {
- iterator(value, index++);
- }
- catch ( e )
- {
- if ( e != $continue ) throw e;
- }
- });
- }
- catch ( e )
- {
- if ( e != $break ) throw e;
- }
- },
-
- all: function( iterator )
- {
- var result = true;
- this.each(function( value, index )
- {
- result = result && !!(iterator || Prototype.K)(value, index);
- if ( !result ) throw $break;
- });
- return result;
- },
-
- any: function( iterator )
- {
- var result = false;
- this.each(function( value, index )
- {
- if ( result = !!(iterator || Prototype.K)(value, index) )
- throw $break;
- });
- return result;
- },
-
- collect: function( iterator )
- {
- var results = [];
- this.each(function( value, index )
- {
- results.push(iterator(value, index));
- });
- return results;
- },
-
- detect: function ( iterator )
- {
- var result;
- this.each(function( value, index )
- {
- if ( iterator(value, index) )
- {
- result = value;
- throw $break;
- }
- });
- return result;
- },
-
- findAll: function( iterator )
- {
- var results = [];
- this.each(function( value, index )
- {
- if ( iterator(value, index) )
- results.push(value);
- });
- return results;
- },
-
- grep: function( pattern, iterator )
- {
- var results = [];
- this.each(function( value, index )
- {
- var stringValue = value.toString();
- if ( stringValue.match(pattern) )
- results.push((iterator || Prototype.K)(value, index));
- })
- return results;
- },
-
- include: function( object )
- {
- var found = false;
- this.each(function( value )
- {
- if ( value == object )
- {
- found = true;
- throw $break;
- }
- });
- return found;
- },
-
- inject: function( memo, iterator )
- {
- this.each(function( value, index )
- {
- memo = iterator(memo, value, index);
- });
- return memo;
- },
-
- invoke: function( method )
- {
- var args = $A(arguments).slice(1);
- return this.collect(function( value )
- {
- return value[method].apply(value, args);
- });
- },
-
- max: function( iterator )
- {
- var result;
- this.each(function( value, index )
- {
- value = (iterator || Prototype.K)(value, index);
- if ( result == undefined || value >= result )
- result = value;
- });
- return result;
- },
-
- min: function( iterator )
- {
- var result;
- this.each(function( value, index )
- {
- value = (iterator || Prototype.K)(value, index);
- if ( result == undefined || value < result )
- result = value;
- });
- return result;
- },
-
- partition: function( iterator )
- {
- var trues = [], falses = [];
- this.each(function( value, index )
- {
- ((iterator || Prototype.K)(value, index) ? trues : falses).push(value);
- });
- return [trues, falses];
- },
-
- pluck: function( property )
- {
- var results = [];
- this.each(function( value, index )
- {
- results.push(value[property]);
- });
- return results;
- },
-
- reject: function( iterator )
- {
- var results = [];
- this.each(function( value, index )
- {
- if ( !iterator(value, index) )
- results.push(value);
- });
- return results;
- },
-
- sortBy: function( iterator )
- {
- return this.collect(function( value, index )
- {
- return {value: value, criteria: iterator(value, index)};
- }).sort(function( left, right )
- {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }).pluck('value');
- },
-
- toArray: function()
- {
- return this.collect(Prototype.K);
- },
-
- zip: function()
- {
- var iterator = Prototype.K, args = $A(arguments);
- if ( typeof args.last() == 'function' )
- iterator = args.pop();
-
- var collections = [this].concat(args).map($A);
- return this.map(function( value, index )
- {
- return iterator(collections.pluck(index));
- });
- },
-
- inspect: function()
- {
- return '#<Enumerable:' + this.toArray().inspect() + '>';
- }
-}
-
-Object.extend(Enumerable, {
- map: Enumerable.collect,
- find: Enumerable.detect,
- select: Enumerable.findAll,
- member: Enumerable.include,
- entries: Enumerable.toArray
-});
-var $A = Array.from = function( iterable )
-{
- if ( !iterable ) return [];
- if ( iterable.toArray )
- {
- return iterable.toArray();
- }
- else
- {
- var results = [];
- for ( var i = 0; i < iterable.length; i++ )
- results.push(iterable[i]);
- return results;
- }
-}
-
-Object.extend(Array.prototype, Enumerable);
-
-if ( !Array.prototype._reverse )
- Array.prototype._reverse = Array.prototype.reverse;
-
-Object.extend(Array.prototype, {
- _each: function( iterator )
- {
- for ( var i = 0; i < this.length; i++ )
- iterator(this[i]);
- },
-
- clear: function()
- {
- this.length = 0;
- return this;
- },
-
- first: function()
- {
- return this[0];
- },
-
- last: function()
- {
- return this[this.length - 1];
- },
-
- compact: function()
- {
- return this.select(function( value )
- {
- return value != undefined || value != null;
- });
- },
-
- flatten: function()
- {
- return this.inject([], function( array, value )
- {
- return array.concat(value && value.constructor == Array ? value.flatten() : [value]);
- });
- },
-
- without: function()
- {
- var values = $A(arguments);
- return this.select(function( value )
- {
- return !values.include(value);
- });
- },
-
- indexOf: function( object )
- {
- for ( var i = 0; i < this.length; i++ )
- if ( this[i] == object ) return i;
- return -1;
- },
-
- reverse: function( inline )
- {
- return (inline !== false ? this : this.toArray())._reverse();
- },
-
- reduce: function()
- {
- return this.length > 1 ? this : this[0];
- },
-
- uniq: function()
- {
- return this.inject([], function( array, value )
- {
- return array.include(value) ? array : array.concat([value]);
- });
- },
-
- inspect: function()
- {
- return '[' + this.map(Object.inspect).join(', ') + ']';
- }
-});
-var Hash = {
- _each: function( iterator )
- {
- for ( var key in this )
- {
- var value = this[key];
- if ( typeof value == 'function' ) continue;
-
- var pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
- },
-
- keys: function()
- {
- return this.pluck('key');
- },
-
- values: function()
- {
- return this.pluck('value');
- },
-
- merge: function( hash )
- {
- return $H(hash).inject($H(this), function( mergedHash, pair )
- {
- mergedHash[pair.key] = pair.value;
- return mergedHash;
- });
- },
-
- toQueryString: function()
- {
- return this.map(function( pair )
- {
- return pair.map(encodeURIComponent).join('=');
- }).join('&');
- },
-
- inspect: function()
- {
- return '#<Hash:{' + this.map(function( pair )
- {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
- }
-}
-
-function $H( object )
-{
- var hash = Object.extend({}, object || {});
- Object.extend(hash, Enumerable);
- Object.extend(hash, Hash);
- return hash;
-}
-ObjectRange = Class.create();
-Object.extend(ObjectRange.prototype, Enumerable);
-Object.extend(ObjectRange.prototype, {
- initialize: function( start, end, exclusive )
- {
- this.start = start;
- this.end = end;
- this.exclusive = exclusive;
- },
-
- _each: function( iterator )
- {
- var value = this.start;
- while ( this.include(value) )
- {
- iterator(value);
- value = value.succ();
- }
- },
-
- include: function( value )
- {
- if ( value < this.start )
- return false;
- if ( this.exclusive )
- return value < this.end;
- return value <= this.end;
- }
-});
-
-var $R = function( start, end, exclusive )
-{
- return new ObjectRange(start, end, exclusive);
-}
-
-var Ajax = {
- getTransport: function()
- {
- return Try.these(function()
- {
- return new XMLHttpRequest()
- }, function()
- {
- return new ActiveXObject('Msxml2.XMLHTTP')
- }, function()
- {
- return new ActiveXObject('Microsoft.XMLHTTP')
- }) || false;
- },
-
- activeRequestCount: 0
-}
-
-Ajax.Responders = {
- responders: [],
-
- _each: function( iterator )
- {
- this.responders._each(iterator);
- },
-
- register: function( responderToAdd )
- {
- if ( !this.include(responderToAdd) )
- this.responders.push(responderToAdd);
- },
-
- unregister: function( responderToRemove )
- {
- this.responders = this.responders.without(responderToRemove);
- },
-
- dispatch: function( callback, request, transport, json )
- {
- this.each(function( responder )
- {
- if ( responder[callback] && typeof responder[callback] == 'function' )
- {
- try
- {
- responder[callback].apply(responder, [request, transport, json]);
- }
- catch ( e )
- {
- }
- }
- });
- }
-};
-
-Object.extend(Ajax.Responders, Enumerable);
-
-Ajax.Responders.register({
- onCreate: function()
- {
- Ajax.activeRequestCount++;
- },
-
- onComplete: function()
- {
- Ajax.activeRequestCount--;
- }
-});
-
-Ajax.Base = function()
-{
-};
-Ajax.Base.prototype = {
- setOptions: function( options )
- {
- this.options = {
- method: 'post',
- asynchronous: true,
- contentType: 'application/x-www-form-urlencoded',
- parameters: ''
- }
- Object.extend(this.options, options || {});
- },
-
- responseIsSuccess: function()
- {
- return this.transport.status == undefined || this.transport.status == 0 ||
- (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- responseIsFailure: function()
- {
- return !this.responseIsSuccess();
- }
-}
-
-Ajax.Request = Class.create();
-Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-
-Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
- initialize: function( url, options )
- {
- this.transport = Ajax.getTransport();
- this.setOptions(options);
- this.request(url);
- },
-
- request: function( url )
- {
- var parameters = this.options.parameters || '';
- if ( parameters.length > 0 ) parameters += '&_=';
-
- /* Simulate other verbs over post */
- if ( this.options.method != 'get' && this.options.method != 'post' )
- {
- parameters += (parameters.length > 0 ? '&' : '') + '_method=' + this.options.method;
- this.options.method = 'post';
- }
-
- try
- {
- this.url = url;
- if ( this.options.method == 'get' && parameters.length > 0 )
- this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
-
- Ajax.Responders.dispatch('onCreate', this, this.transport);
-
- this.transport.open(this.options.method, this.url, this.options.asynchronous);
-
- if ( this.options.asynchronous )
- setTimeout(function()
- {
- this.respondToReadyState(1)
- }.bind(this), 10);
-
- this.transport.onreadystatechange = this.onStateChange.bind(this);
- this.setRequestHeaders();
-
- var body = this.options.postBody ? this.options.postBody : parameters;
- this.transport.send(this.options.method == 'post' ? body : null);
-
- /* Force Firefox to handle ready state 4 for synchronous requests */
- if ( !this.options.asynchronous && this.transport.overrideMimeType )
- this.onStateChange();
-
- }
- catch ( e )
- {
- this.dispatchException(e);
- }
- },
-
- setRequestHeaders: function()
- {
- var requestHeaders = ['X-Requested-With', 'XMLHttpRequest',
- 'X-Prototype-Version', Prototype.Version,
- 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
-
- if ( this.options.method == 'post' )
- {
- requestHeaders.push('Content-type', this.options.contentType);
-
- /* Force "Connection: close" for Mozilla browsers to work around
- * a bug where XMLHttpReqeuest sends an incorrect Content-length
- * header. See Mozilla Bugzilla #246651.
- */
- if ( this.transport.overrideMimeType )
- requestHeaders.push('Connection', 'close');
- }
-
- if ( this.options.requestHeaders )
- requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
-
- for ( var i = 0; i < requestHeaders.length; i += 2 )
- this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i + 1]);
- },
-
- onStateChange: function()
- {
- var readyState = this.transport.readyState;
- if ( readyState != 1 )
- this.respondToReadyState(this.transport.readyState);
- },
-
- header: function( name )
- {
- try
- {
- return this.transport.getResponseHeader(name);
- }
- catch ( e )
- {
- }
- },
-
- evalJSON: function()
- {
- try
- {
- return eval('(' + this.header('X-JSON') + ')');
- }
- catch ( e )
- {
- }
- },
-
- evalResponse: function()
- {
- try
- {
- return eval(this.transport.responseText);
- }
- catch ( e )
- {
- this.dispatchException(e);
- }
- },
-
- respondToReadyState: function( readyState )
- {
- var event = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
-
- if ( event == 'Complete' )
- {
- try
- {
- (this.options['on' + this.transport.status] ||
- this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] ||
- Prototype.emptyFunction)(transport, json);
- }
- catch ( e )
- {
- this.dispatchException(e);
- }
-
- if ( (this.header('Content-type') || '').match(/^text\/javascript/i) )
- this.evalResponse();
- }
-
- try
- {
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
- }
- catch ( e )
- {
- this.dispatchException(e);
- }
-
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if ( event == 'Complete' )
- this.transport.onreadystatechange = Prototype.emptyFunction;
- },
-
- dispatchException: function( exception )
- {
- (this.options.onException || Prototype.emptyFunction)(this, exception);
- Ajax.Responders.dispatch('onException', this, exception);
- }
-});
-
-Ajax.Updater = Class.create();
-
-Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
- initialize: function( container, url, options )
- {
- this.containers = {
- success: container.success ? $(container.success) : $(container),
- failure: container.failure ? $(container.failure) : (container.success ? null : $(container))
- }
-
- this.transport = Ajax.getTransport();
- this.setOptions(options);
-
- var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function( transport, object )
- {
- this.updateContent();
- onComplete(transport, object);
- }).bind(this);
-
- this.request(url);
- },
-
- updateContent: function()
- {
- var receiver = this.responseIsSuccess() ? this.containers.success : this.containers.failure;
- var response = this.transport.responseText;
-
- if ( !this.options.evalScripts )
- response = response.stripScripts();
-
- if ( receiver )
- {
- if ( this.options.insertion )
- {
- new this.options.insertion(receiver, response);
- }
- else
- {
- Element.update(receiver, response);
- }
- }
-
- if ( this.responseIsSuccess() )
- {
- if ( this.onComplete )
- setTimeout(this.onComplete.bind(this), 10);
- }
- }
-});
-
-Ajax.PeriodicalUpdater = Class.create();
-Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
- initialize: function( container, url, options )
- {
- this.setOptions(options);
- this.onComplete = this.options.onComplete;
-
- this.frequency = (this.options.frequency || 2);
- this.decay = (this.options.decay || 1);
-
- this.updater = {};
- this.container = container;
- this.url = url;
-
- this.start();
- },
-
- start: function()
- {
- this.options.onComplete = this.updateComplete.bind(this);
- this.onTimerEvent();
- },
-
- stop: function()
- {
- this.updater.options.onComplete = undefined;
- clearTimeout(this.timer);
- (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
- },
-
- updateComplete: function( request )
- {
- if ( this.options.decay )
- {
- this.decay = (request.responseText == this.lastText ? this.decay * this.options.decay : 1);
-
- this.lastText = request.responseText;
- }
- this.timer = setTimeout(this.onTimerEvent.bind(this), this.decay * this.frequency * 1000);
- },
-
- onTimerEvent: function()
- {
- this.updater = new Ajax.Updater(this.container, this.url, this.options);
- }
-});
-function $()
-{
- var results = [], element;
- for ( var i = 0; i < arguments.length; i++ )
- {
- element = arguments[i];
- if ( typeof element == 'string' )
- element = document.getElementById(element);
- results.push(Element.extend(element));
- }
- return results.reduce();
-}
-
-document.getElementsByClassName = function( className, parentElement )
-{
- var children = ($(parentElement) || document.body).getElementsByTagName('*');
- return $A(children).inject([], function( elements, child )
- {
- if ( child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")) )
- elements.push(Element.extend(child));
- return elements;
- });
-}
-
-/*--------------------------------------------------------------------------*/
-
-if ( !window.Element )
- var Element = new Object();
-
-Element.extend = function( element )
-{
- if ( !element ) return;
- if ( _nativeExtensions || element.nodeType == 3 ) return element;
-
- if ( !element._extended && element.tagName && element != window )
- {
- var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
-
- if ( element.tagName == 'FORM' )
- Object.extend(methods, Form.Methods);
- if ( ['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName) )
- Object.extend(methods, Form.Element.Methods);
-
- for ( var property in methods )
- {
- var value = methods[property];
- if ( typeof value == 'function' )
- element[property] = cache.findOrStore(value);
- }
- }
-
- element._extended = true;
- return element;
-}
-
-Element.extend.cache = {
- findOrStore: function( value )
- {
- return this[value] = this[value] || function()
- {
- return value.apply(null, [this].concat($A(arguments)));
- }
- }
-}
-
-Element.Methods = {
- visible: function( element )
- {
- return $(element).style.display != 'none';
- },
-
- toggle: function( element )
- {
- element = $(element);
- Element[Element.visible(element) ? 'hide' : 'show'](element);
- return element;
- },
-
- hide: function( element )
- {
- $(element).style.display = 'none';
- return element;
- },
-
- show: function( element )
- {
- $(element).style.display = '';
- return element;
- },
-
- remove: function( element )
- {
- element = $(element);
- element.parentNode.removeChild(element);
- return element;
- },
-
- update: function( element, html )
- {
- $(element).innerHTML = html.stripScripts();
- setTimeout(function()
- {
- html.evalScripts()
- }, 10);
- return element;
- },
-
- replace: function( element, html )
- {
- element = $(element);
- if ( element.outerHTML )
- {
- element.outerHTML = html.stripScripts();
- }
- else
- {
- var range = element.ownerDocument.createRange();
- range.selectNodeContents(element);
- element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);
- }
- setTimeout(function()
- {
- html.evalScripts()
- }, 10);
- return element;
- },
-
- inspect: function( element )
- {
- element = $(element);
- var result = '<' + element.tagName.toLowerCase();
- $H({'id': 'id', 'className': 'class'}).each(function( pair )
- {
- var property = pair.first(), attribute = pair.last();
- var value = (element[property] || '').toString();
- if ( value ) result += ' ' + attribute + '=' + value.inspect(true);
- });
- return result + '>';
- },
-
- recursivelyCollect: function( element, property )
- {
- element = $(element);
- var elements = [];
- while ( element = element[property] )
- if ( element.nodeType == 1 )
- elements.push(Element.extend(element));
- return elements;
- },
-
- ancestors: function( element )
- {
- return $(element).recursivelyCollect('parentNode');
- },
-
- descendants: function( element )
- {
- element = $(element);
- return $A(element.getElementsByTagName('*'));
- },
-
- previousSiblings: function( element )
- {
- return $(element).recursivelyCollect('previousSibling');
- },
-
- nextSiblings: function( element )
- {
- return $(element).recursivelyCollect('nextSibling');
- },
-
- siblings: function( element )
- {
- element = $(element);
- return element.previousSiblings().reverse().concat(element.nextSiblings());
- },
-
- match: function( element, selector )
- {
- element = $(element);
- if ( typeof selector == 'string' )
- selector = new Selector(selector);
- return selector.match(element);
- },
-
- up: function( element, expression, index )
- {
- return Selector.findElement($(element).ancestors(), expression, index);
- },
-
- down: function( element, expression, index )
- {
- return Selector.findElement($(element).descendants(), expression, index);
- },
-
- previous: function( element, expression, index )
- {
- return Selector.findElement($(element).previousSiblings(), expression, index);
- },
-
- next: function( element, expression, index )
- {
- return Selector.findElement($(element).nextSiblings(), expression, index);
- },
-
- getElementsBySelector: function()
- {
- var args = $A(arguments), element = $(args.shift());
- return Selector.findChildElements(element, args);
- },
-
- getElementsByClassName: function( element, className )
- {
- element = $(element);
- return document.getElementsByClassName(className, element);
- },
-
- getHeight: function( element )
- {
- element = $(element);
- return element.offsetHeight;
- },
-
- classNames: function( element )
- {
- return new Element.ClassNames(element);
- },
-
- hasClassName: function( element, className )
- {
- if ( !(element = $(element)) ) return;
- return Element.classNames(element).include(className);
- },
-
- addClassName: function( element, className )
- {
- if ( !(element = $(element)) ) return;
- Element.classNames(element).add(className);
- return element;
- },
-
- removeClassName: function( element, className )
- {
- if ( !(element = $(element)) ) return;
- Element.classNames(element).remove(className);
- return element;
- },
-
- observe: function()
- {
- Event.observe.apply(Event, arguments);
- return $A(arguments).first();
- },
-
- stopObserving: function()
- {
- Event.stopObserving.apply(Event, arguments);
- return $A(arguments).first();
- },
-
-// removes whitespace-only text node children
- cleanWhitespace: function( element )
- {
- element = $(element);
- var node = element.firstChild;
- while ( node )
- {
- var nextNode = node.nextSibling;
- if ( node.nodeType == 3 && !/\S/.test(node.nodeValue) )
- element.removeChild(node);
- node = nextNode;
- }
- return element;
- },
-
- empty: function( element )
- {
- return $(element).innerHTML.match(/^\s*$/);
- },
-
- childOf: function( element, ancestor )
- {
- element = $(element),ancestor = $(ancestor);
- while ( element = element.parentNode )
- if ( element == ancestor ) return true;
- return false;
- },
-
- scrollTo: function( element )
- {
- element = $(element);
- var x = element.x ? element.x : element.offsetLeft,
- y = element.y ? element.y : element.offsetTop;
- window.scrollTo(x, y);
- return element;
- },
-
- getStyle: function( element, style )
- {
- element = $(element);
- var value = element.style[style.camelize()];
- if ( !value )
- {
- if ( document.defaultView && document.defaultView.getComputedStyle )
- {
- var css = document.defaultView.getComputedStyle(element, null);
- value = css ? css.getPropertyValue(style) : null;
- }
- else if ( element.currentStyle )
- {
- value = element.currentStyle[style.camelize()];
- }
- }
-
- if ( window.opera && ['left', 'top', 'right', 'bottom'].include(style) )
- if ( Element.getStyle(element, 'position') == 'static' ) value = 'auto';
-
- return value == 'auto' ? null : value;
- },
-
- setStyle: function( element, style )
- {
- element = $(element);
- for ( var name in style )
- element.style[name.camelize()] = style[name];
- return element;
- },
-
- getDimensions: function( element )
- {
- element = $(element);
- if ( Element.getStyle(element, 'display') != 'none' )
- return {width: element.offsetWidth, height: element.offsetHeight};
-
- // All *Width and *Height properties give 0 on elements with display none,
- // so enable the element temporarily
- var els = element.style;
- var originalVisibility = els.visibility;
- var originalPosition = els.position;
- els.visibility = 'hidden';
- els.position = 'absolute';
- els.display = '';
- var originalWidth = element.clientWidth;
- var originalHeight = element.clientHeight;
- els.display = 'none';
- els.position = originalPosition;
- els.visibility = originalVisibility;
- return {width: originalWidth, height: originalHeight};
- },
-
- makePositioned: function( element )
- {
- element = $(element);
- var pos = Element.getStyle(element, 'position');
- if ( pos == 'static' || !pos )
- {
- element._madePositioned = true;
- element.style.position = 'relative';
- // Opera returns the offset relative to the positioning context, when an
- // element is position relative but top and left have not been defined
- if ( window.opera )
- {
- element.style.top = 0;
- element.style.left = 0;
- }
- }
- return element;
- },
-
- undoPositioned: function( element )
- {
- element = $(element);
- if ( element._madePositioned )
- {
- element._madePositioned = undefined;
- element.style.position =
- element.style.top = element.style.left = element.style.bottom = element.style.right = '';
- }
- return element;
- },
-
- makeClipping: function( element )
- {
- element = $(element);
- if ( element._overflow ) return;
- element._overflow = element.style.overflow || 'auto';
- if ( (Element.getStyle(element, 'overflow') || 'visible') != 'hidden' )
- element.style.overflow = 'hidden';
- return element;
- },
-
- undoClipping: function( element )
- {
- element = $(element);
- if ( !element._overflow ) return;
- element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
- element._overflow = null;
- return element;
- }
-}
-
-// IE is missing .innerHTML support for TABLE-related elements
-if ( document.all )
-{
- Element.Methods.update = function( element, html )
- {
- element = $(element);
- var tagName = element.tagName.toUpperCase();
- if ( ['THEAD','TBODY','TR','TD'].indexOf(tagName) > -1 )
- {
- var div = document.createElement('div');
- switch ( tagName )
- {
- case 'THEAD':
- case 'TBODY':
- div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
- depth = 2;
- break;
- case 'TR':
- div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
- depth = 3;
- break;
- case 'TD':
- div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
- depth = 4;
- }
- $A(element.childNodes).each(function( node )
- {
- element.removeChild(node)
- });
- depth.times(function()
- {
- div = div.firstChild
- });
-
- $A(div.childNodes).each(function( node )
- {
- element.appendChild(node)
- });
- }
- else
- {
- element.innerHTML = html.stripScripts();
- }
- setTimeout(function()
- {
- html.evalScripts()
- }, 10);
- return element;
- }
-}
-
-Object.extend(Element, Element.Methods);
-
-var _nativeExtensions = false;
-
-if ( !window.HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent) )
-{
- /* Emulate HTMLElement, HTMLFormElement, HTMLInputElement, HTMLTextAreaElement,
-and HTMLSelectElement in Safari */
- ['', 'Form', 'Input', 'TextArea', 'Select'].each(function( tag )
- {
- var klass = window['HTML' + tag + 'Element'] = {};
- klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
- });
-}
-
-Element.addMethods = function( methods )
-{
- Object.extend(Element.Methods, methods || {});
-
- function copy( methods, destination )
- {
- var cache = Element.extend.cache;
- for ( var property in methods )
- {
- var value = methods[property];
- destination[property] = cache.findOrStore(value);
- }
- }
-
- if ( typeof HTMLElement != 'undefined' )
- {
- copy(Element.Methods, HTMLElement.prototype);
- copy(Form.Methods, HTMLFormElement.prototype);
- [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function( klass )
- {
- copy(Form.Element.Methods, klass.prototype);
- });
- _nativeExtensions = true;
- }
-}
-
-var Toggle = new Object();
-Toggle.display = Element.toggle;
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.Insertion = function( adjacency )
-{
- this.adjacency = adjacency;
-}
-
-Abstract.Insertion.prototype = {
- initialize: function( element, content )
- {
- this.element = $(element);
- this.content = content.stripScripts();
-
- if ( this.adjacency && this.element.insertAdjacentHTML )
- {
- try
- {
- this.element.insertAdjacentHTML(this.adjacency, this.content);
- }
- catch ( e )
- {
- var tagName = this.element.tagName.toLowerCase();
- if ( tagName == 'tbody' || tagName == 'tr' )
- {
- this.insertContent(this.contentFromAnonymousTable());
- }
- else
- {
- throw e;
- }
- }
- }
- else
- {
- this.range = this.element.ownerDocument.createRange();
- if ( this.initializeRange ) this.initializeRange();
- this.insertContent([this.range.createContextualFragment(this.content)]);
- }
-
- setTimeout(function()
- {
- content.evalScripts()
- }, 10);
- },
-
- contentFromAnonymousTable: function()
- {
- var div = document.createElement('div');
- div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
- return $A(div.childNodes[0].childNodes[0].childNodes);
- }
-}
-
-var Insertion = new Object();
-
-Insertion.Before = Class.create();
-Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
- initializeRange: function()
- {
- this.range.setStartBefore(this.element);
- },
-
- insertContent: function( fragments )
- {
- fragments.each((function( fragment )
- {
- this.element.parentNode.insertBefore(fragment, this.element);
- }).bind(this));
- }
-});
-
-Insertion.Top = Class.create();
-Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
- initializeRange: function()
- {
- this.range.selectNodeContents(this.element);
- this.range.collapse(true);
- },
-
- insertContent: function( fragments )
- {
- fragments.reverse(false).each((function( fragment )
- {
- this.element.insertBefore(fragment, this.element.firstChild);
- }).bind(this));
- }
-});
-
-Insertion.Bottom = Class.create();
-Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
- initializeRange: function()
- {
- this.range.selectNodeContents(this.element);
- this.range.collapse(this.element);
- },
-
- insertContent: function( fragments )
- {
- fragments.each((function( fragment )
- {
- this.element.appendChild(fragment);
- }).bind(this));
- }
-});
-
-Insertion.After = Class.create();
-Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
- initializeRange: function()
- {
- this.range.setStartAfter(this.element);
- },
-
- insertContent: function( fragments )
- {
- fragments.each((function( fragment )
- {
- this.element.parentNode.insertBefore(fragment, this.element.nextSibling);
- }).bind(this));
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
- initialize: function( element )
- {
- this.element = $(element);
- },
-
- _each: function( iterator )
- {
- this.element.className.split(/\s+/).select(function( name )
- {
- return name.length > 0;
- })._each(iterator);
- },
-
- set: function( className )
- {
- this.element.className = className;
- },
-
- add: function( classNameToAdd )
- {
- if ( this.include(classNameToAdd) ) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
- },
-
- remove: function( classNameToRemove )
- {
- if ( !this.include(classNameToRemove) ) return;
- this.set(this.select(function( className )
- {
- return className != classNameToRemove;
- }).join(' '));
- },
-
- toString: function()
- {
- return this.toArray().join(' ');
- }
-}
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-var Selector = Class.create();
-Selector.prototype = {
- initialize: function( expression )
- {
- this.params = {classNames: []};
- this.expression = expression.toString().strip();
- this.parseExpression();
- this.compileMatcher();
- },
-
- parseExpression: function()
- {
- function abort( message )
- {
- throw 'Parse error in selector: ' + message;
- }
-
- if ( this.expression == '' ) abort('empty expression');
-
- var params = this.params, expr = this.expression, match, modifier, clause, rest;
- while ( match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i) )
- {
- params.attributes = params.attributes || [];
- params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
- expr = match[1];
- }
-
- if ( expr == '*' ) return this.params.wildcard = true;
-
- while ( match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i) )
- {
- modifier = match[1],clause = match[2],rest = match[3];
- switch ( modifier )
- {
- case '#': params.id = clause; break;
- case '.': params.classNames.push(clause); break;
- case '':
- case undefined: params.tagName = clause.toUpperCase(); break;
- default: abort(expr.inspect());
- }
- expr = rest;
- }
-
- if ( expr.length > 0 ) abort(expr.inspect());
- },
-
- buildMatchExpression: function()
- {
- var params = this.params, conditions = [], clause;
-
- if ( params.wildcard )
- conditions.push('true');
- if ( clause = params.id )
- conditions.push('element.id == ' + clause.inspect());
- if ( clause = params.tagName )
- conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
- if ( (clause = params.classNames).length > 0 )
- for ( var i = 0; i < clause.length; i++ )
- conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
- if ( clause = params.attributes )
- {
- clause.each(function( attribute )
- {
- var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
- var splitValueBy = function( delimiter )
- {
- return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
- }
-
- switch ( attribute.operator )
- {
- case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
- case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() +
- ')'); break;
- case '|=': conditions.push(splitValueBy('-') + '.first().toUpperCase() == ' +
- attribute.value.toUpperCase().inspect()); break;
- case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
- case '':
- case undefined: conditions.push(value + ' != null'); break;
- default: throw 'Unknown operator ' + attribute.operator + ' in selector';
- }
- });
- }
-
- return conditions.join(' && ');
- },
-
- compileMatcher: function()
- {
- this.match = new Function('element', 'if (!element.tagName) return false; \
- return ' + this.buildMatchExpression());
- },
-
- findElements: function( scope )
- {
- var element;
-
- if ( element = $(this.params.id) )
- if ( this.match(element) )
- if ( !scope || Element.childOf(element, scope) )
- return [element];
-
- scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
-
- var results = [];
- for ( var i = 0; i < scope.length; i++ )
- if ( this.match(element = scope[i]) )
- results.push(Element.extend(element));
-
- return results;
- },
-
- toString: function()
- {
- return this.expression;
- }
-}
-
-Object.extend(Selector, {
- matchElements: function( elements, expression )
- {
- var selector = new Selector(expression);
- return elements.select(selector.match.bind(selector));
- },
-
- findElement: function( elements, expression, index )
- {
- if ( typeof expression == 'number' ) index = expression,expression = false;
- return Selector.matchElements(elements, expression || '*')[index || 0];
- },
-
- findChildElements: function( element, expressions )
- {
- return expressions.map(function( expression )
- {
- return expression.strip().split(/\s+/).inject([null], function( results, expr )
- {
- var selector = new Selector(expr);
- return results.inject([], function( elements, result )
- {
- return elements.concat(selector.findElements(result || element));
- });
- });
- }).flatten();
- }
-});
-
-function $$()
-{
- return Selector.findChildElements(document, $A(arguments));
-}
-var Form = {
- reset: function( form )
- {
- $(form).reset();
- return form;
- }
-};
-
-Form.Methods = {
- serialize: function( form )
- {
- var elements = Form.getElements($(form));
- var queryComponents = new Array();
-
- for ( var i = 0; i < elements.length; i++ )
- {
- var queryComponent = Form.Element.serialize(elements[i]);
- if ( queryComponent )
- queryComponents.push(queryComponent);
- }
-
- return queryComponents.join('&');
- },
-
- getElements: function( form )
- {
- form = $(form);
- var elements = new Array();
-
- for ( var tagName in Form.Element.Serializers )
- {
- var tagElements = form.getElementsByTagName(tagName);
- for ( var j = 0; j < tagElements.length; j++ )
- elements.push(tagElements[j]);
- }
- return elements;
- },
-
- getInputs: function( form, typeName, name )
- {
- form = $(form);
- var inputs = form.getElementsByTagName('input');
-
- if ( !typeName && !name )
- return inputs;
-
- var matchingInputs = new Array();
- for ( var i = 0; i < inputs.length; i++ )
- {
- var input = inputs[i];
- if ( (typeName && input.type != typeName) || (name && input.name != name) )
- continue;
- matchingInputs.push(input);
- }
-
- return matchingInputs;
- },
-
- disable: function( form )
- {
- form = $(form);
- var elements = Form.getElements(form);
- for ( var i = 0; i < elements.length; i++ )
- {
- var element = elements[i];
- element.blur();
- element.disabled = 'true';
- }
- return form;
- },
-
- enable: function( form )
- {
- form = $(form);
- var elements = Form.getElements(form);
- for ( var i = 0; i < elements.length; i++ )
- {
- var element = elements[i];
- element.disabled = '';
- }
- return form;
- },
-
- findFirstElement: function( form )
- {
- return Form.getElements(form).find(function( element )
- {
- return element.type != 'hidden' && !element.disabled &&
- ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
- });
- },
-
- focusFirstElement: function( form )
- {
- form = $(form);
- Field.activate(Form.findFirstElement(form));
- return form;
- }
-}
-
-Object.extend(Form, Form.Methods);
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element = {
- focus: function( element )
- {
- $(element).focus();
- return element;
- },
-
- select: function( element )
- {
- $(element).select();
- return element;
- }
-}
-
-Form.Element.Methods = {
- serialize: function( element )
- {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if ( parameter )
- {
- var key = encodeURIComponent(parameter[0]);
- if ( key.length == 0 ) return;
-
- if ( parameter[1].constructor != Array )
- parameter[1] = [parameter[1]];
-
- return parameter[1].map(function( value )
- {
- return key + '=' + encodeURIComponent(value);
- }).join('&');
- }
- },
-
- getValue: function( element )
- {
- element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if ( parameter )
- return parameter[1];
- },
-
- clear: function( element )
- {
- $(element).value = '';
- return element;
- },
-
- present: function( element )
- {
- return $(element).value != '';
- },
-
- activate: function( element )
- {
- element = $(element);
- element.focus();
- if ( element.select )
- element.select();
- return element;
- },
-
- disable: function( element )
- {
- element = $(element);
- element.disabled = '';
- return element;
- },
-
- enable: function( element )
- {
- element = $(element);
- element.blur();
- element.disabled = 'true';
- return element;
- }
-}
-
-Object.extend(Form.Element, Form.Element.Methods);
-var Field = Form.Element;
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element.Serializers = {
- input: function( element )
- {
- switch ( element.type.toLowerCase() )
- {
- case 'checkbox':
- case 'radio':
- return Form.Element.Serializers.inputSelector(element);
- default:
- return Form.Element.Serializers.textarea(element);
- }
- return false;
- },
-
- inputSelector: function( element )
- {
- if ( element.checked )
- return [element.name, element.value];
- },
-
- textarea: function( element )
- {
- return [element.name, element.value];
- },
-
- select: function( element )
- {
- return Form.Element.Serializers[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element);
- },
-
- selectOne: function( element )
- {
- var value = '', opt, index = element.selectedIndex;
- if ( index >= 0 )
- {
- opt = element.options[index];
- value = opt.value || opt.text;
- }
- return [element.name, value];
- },
-
- selectMany: function( element )
- {
- var value = [];
- for ( var i = 0; i < element.length; i++ )
- {
- var opt = element.options[i];
- if ( opt.selected )
- value.push(opt.value || opt.text);
- }
- return [element.name, value];
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.TimedObserver = function()
-{
-}
-Abstract.TimedObserver.prototype = {
- initialize: function( element, frequency, callback )
- {
- this.frequency = frequency;
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- this.registerCallback();
- },
-
- registerCallback: function()
- {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
-
- onTimerEvent: function()
- {
- var value = this.getValue();
- if ( this.lastValue != value )
- {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- }
-}
-
-Form.Element.Observer = Class.create();
-Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function()
- {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.Observer = Class.create();
-Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
- getValue: function()
- {
- return Form.serialize(this.element);
- }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = function()
-{
-}
-Abstract.EventObserver.prototype = {
- initialize: function( element, callback )
- {
- this.element = $(element);
- this.callback = callback;
-
- this.lastValue = this.getValue();
- if ( this.element.tagName.toLowerCase() == 'form' )
- this.registerFormCallbacks();
- else
- this.registerCallback(this.element);
- },
-
- onElementEvent: function()
- {
- var value = this.getValue();
- if ( this.lastValue != value )
- {
- this.callback(this.element, value);
- this.lastValue = value;
- }
- },
-
- registerFormCallbacks: function()
- {
- var elements = Form.getElements(this.element);
- for ( var i = 0; i < elements.length; i++ )
- this.registerCallback(elements[i]);
- },
-
- registerCallback: function( element )
- {
- if ( element.type )
- {
- switch ( element.type.toLowerCase() )
- {
- case 'checkbox':
- case 'radio':
- Event.observe(element, 'click', this.onElementEvent.bind(this));
- break;
- default:
- Event.observe(element, 'change', this.onElementEvent.bind(this));
- break;
- }
- }
- }
-}
-
-Form.Element.EventObserver = Class.create();
-Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function()
- {
- return Form.Element.getValue(this.element);
- }
-});
-
-Form.EventObserver = Class.create();
-Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
- getValue: function()
- {
- return Form.serialize(this.element);
- }
-});
-if ( !window.Event )
-{
- var Event = new Object();
-}
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
- KEY_HOME: 36,
- KEY_END: 35,
- KEY_PAGEUP: 33,
- KEY_PAGEDOWN: 34,
-
- element: function( event )
- {
- return event.target || event.srcElement;
- },
-
- isLeftClick: function( event )
- {
- return (((event.which) && (event.which == 1)) || ((event.button) && (event.button == 1)));
- },
-
- pointerX: function( event )
- {
- return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
- },
-
- pointerY: function( event )
- {
- return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
- },
-
- stop: function( event )
- {
- if ( event.preventDefault )
- {
- event.preventDefault();
- event.stopPropagation();
- }
- else
- {
- event.returnValue = false;
- event.cancelBubble = true;
- }
- },
-
-// find the first node with the given tagName, starting from the
-// node the event was triggered on; traverses the DOM upwards
- findElement: function( event, tagName )
- {
- var element = Event.element(event);
- while ( element.parentNode && (!element.tagName || (element.tagName.toUpperCase() != tagName.toUpperCase())) )
- element = element.parentNode;
- return element;
- },
-
- observers: false,
-
- _observeAndCache: function( element, name, observer, useCapture )
- {
- if ( !this.observers ) this.observers = [];
- if ( element.addEventListener )
- {
- this.observers.push([element, name, observer, useCapture]);
- element.addEventListener(name, observer, useCapture);
- }
- else if ( element.attachEvent )
- {
- this.observers.push([element, name, observer, useCapture]);
- element.attachEvent('on' + name, observer);
- }
- },
-
- unloadCache: function()
- {
- if ( !Event.observers ) return;
- for ( var i = 0; i < Event.observers.length; i++ )
- {
- Event.stopObserving.apply(this, Event.observers[i]);
- Event.observers[i][0] = null;
- }
- Event.observers = false;
- },
-
- observe: function( element, name, observer, useCapture )
- {
- element = $(element);
- useCapture = useCapture || false;
-
- if ( name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.attachEvent) )
- name = 'keydown';
-
- Event._observeAndCache(element, name, observer, useCapture);
- },
-
- stopObserving: function( element, name, observer, useCapture )
- {
- element = $(element);
- useCapture = useCapture || false;
-
- if ( name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.detachEvent) )
- name = 'keydown';
-
- if ( element.removeEventListener )
- {
- element.removeEventListener(name, observer, useCapture);
- }
- else if ( element.detachEvent )
- {
- try
- {
- element.detachEvent('on' + name, observer);
- }
- catch ( e )
- {
- }
- }
- }
-});
-
-/* prevent memory leaks in IE */
-if ( navigator.appVersion.match(/\bMSIE\b/) )
- Event.observe(window, 'unload', Event.unloadCache, false);
-var Position = {
-// set to true if needed, warning: firefox performance problems
-// NOT neeeded for page scrolling, only if draggable contained in
-// scrollable elements
- includeScrollOffsets: false,
-
-// must be called before calling withinIncludingScrolloffset, every time the
-// page is scrolled
- prepare: function()
- {
- this.deltaX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
- this.deltaY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
- },
-
- realOffset: function( element )
- {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- }
- while ( element );
- return [valueL, valueT];
- },
-
- cumulativeOffset: function( element )
- {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- }
- while ( element );
- return [valueL, valueT];
- },
-
- positionedOffset: function( element )
- {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if ( element )
- {
- p = Element.getStyle(element, 'position');
- if ( p == 'relative' || p == 'absolute' ) break;
- }
- }
- while ( element );
- return [valueL, valueT];
- },
-
- offsetParent: function( element )
- {
- if ( element.offsetParent ) return element.offsetParent;
- if ( element == document.body ) return element;
-
- while ( (element = element.parentNode) && element != document.body )
- if ( Element.getStyle(element, 'position') != 'static' )
- return element;
-
- return document.body;
- },
-
-// caches x/y coordinate pair to use with overlap
- within: function( element, x, y )
- {
- if ( this.includeScrollOffsets )
- return this.withinIncludingScrolloffsets(element, x, y);
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
-
- return (y >= this.offset[1] && y < this.offset[1] + element.offsetHeight && x >= this.offset[0] &&
- x < this.offset[0] + element.offsetWidth);
- },
-
- withinIncludingScrolloffsets: function( element, x, y )
- {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache[0] - this.deltaX;
- this.ycomp = y + offsetcache[1] - this.deltaY;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + element.offsetHeight &&
- this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + element.offsetWidth);
- },
-
-// within must be called directly before
- overlap: function( mode, element )
- {
- if ( !mode ) return 0;
- if ( mode == 'vertical' )
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) / element.offsetHeight;
- if ( mode == 'horizontal' )
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) / element.offsetWidth;
- },
-
- page: function( forElement )
- {
- var valueT = 0, valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if ( element.offsetParent == document.body )
- if ( Element.getStyle(element, 'position') == 'absolute' ) break;
-
- }
- while ( element = element.offsetParent );
-
- element = forElement;
- do {
- if ( !window.opera || element.tagName == 'BODY' )
- {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- }
- }
- while ( element = element.parentNode );
-
- return [valueL, valueT];
- },
-
- clone: function( source, target )
- {
- var options = Object.extend({
- setLeft: true,
- setTop: true,
- setWidth: true,
- setHeight: true,
- offsetTop: 0,
- offsetLeft: 0
- }, arguments[2] || {})
-
- // find page position of source
- source = $(source);
- var p = Position.page(source);
-
- // find coordinate system to use
- target = $(target);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
- if ( Element.getStyle(target, 'position') == 'absolute' )
- {
- parent = Position.offsetParent(target);
- delta = Position.page(parent);
- }
-
- // correct by body offsets (fixes Safari)
- if ( parent == document.body )
- {
- delta[0] -= document.body.offsetLeft;
- delta[1] -= document.body.offsetTop;
- }
-
- // set position
- if ( options.setLeft ) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
- if ( options.setTop ) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
- if ( options.setWidth ) target.style.width = source.offsetWidth + 'px';
- if ( options.setHeight ) target.style.height = source.offsetHeight + 'px';
- },
-
- absolutize: function( element )
- {
- element = $(element);
- if ( element.style.position == 'absolute' ) return;
- Position.prepare();
-
- var offsets = Position.positionedOffset(element);
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';
- ;
- element.style.left = left + 'px';
- ;
- element.style.width = width + 'px';
- ;
- element.style.height = height + 'px';
- ;
- },
-
- relativize: function( element )
- {
- element = $(element);
- if ( element.style.position == 'relative' ) return;
- Position.prepare();
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- }
-}
-
-// Safari returns margins on body which is incorrect if the child is absolutely
-// positioned. For performance reasons, redefine Position.cumulativeOffset for
-// KHTML/WebKit only.
-if ( /Konqueror|Safari|KHTML/.test(navigator.userAgent) )
-{
- Position.cumulativeOffset = function( element )
- {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if ( element.offsetParent == document.body )
- if ( Element.getStyle(element, 'position') == 'absolute' ) break;
-
- element = element.offsetParent;
- }
- while ( element );
-
- return [valueL, valueT];
- }
-}
-
-Element.addMethods();
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-// script.aculo.us scriptaculous.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
-
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var Scriptaculous = {
- Version: '1.6.4',
- require: function( libraryName )
- {
- // inserting via DOM fails in Safari 2.0, so brute force approach
- document.write('<script type="text/javascript" src="' + libraryName + '"></script>');
- },
- load: function()
- {
- if ( (typeof Prototype == 'undefined') || (typeof Element == 'undefined') ||
- (typeof Element.Methods == 'undefined') ||
- parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]) < 1.5 )
- throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0");
-
- $A(document.getElementsByTagName("script")).findAll(function( s )
- {
- return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
- }).each(function( s )
- {
- var path = s.src.replace(/scriptaculous\.js(\?.*)?$/, '');
- var includes = s.src.match(/\?.*load=([a-z,]*)/);
- (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(function( include )
- {
- Scriptaculous.require(path + include + '.js')
- });
- });
- }
-}
-
-Scriptaculous.load();
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-// script.aculo.us slider.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
-
-// Copyright (c) 2005 Marty Haught, Thomas Fuchs
-//
-// See http://script.aculo.us for more info
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-if ( !Control ) var Control = {};
-Control.Slider = Class.create();
-
-// options:
-// axis: 'vertical', or 'horizontal' (default)
-//
-// callbacks:
-// onChange(value)
-// onSlide(value)
-Control.Slider.prototype = {
- initialize: function( handle, track, options )
- {
- var slider = this;
-
- if ( handle instanceof Array )
- {
- this.handles = handle.collect(function( e )
- {
- return $(e)
- });
- }
- else
- {
- this.handles = [$(handle)];
- }
-
- this.track = $(track);
- this.options = options || {};
-
- this.axis = this.options.axis || 'horizontal';
- this.increment = this.options.increment || 1;
- this.step = parseInt(this.options.step || '1');
- this.range = this.options.range || $R(0, 1);
-
- this.value = 0;
- // assure backwards compat
- this.values = this.handles.map(function()
- {
- return 0
- });
- this.spans = this.options.spans ? this.options.spans.map(function( s )
- {
- return $(s)
- }) : false;
- this.options.startSpan = $(this.options.startSpan || null);
- this.options.endSpan = $(this.options.endSpan || null);
-
- this.restricted = this.options.restricted || false;
-
- this.maximum = this.options.maximum || this.range.end;
- this.minimum = this.options.minimum || this.range.start;
-
- // Will be used to align the handle onto the track, if necessary
- this.alignX = parseInt(this.options.alignX || '0');
- this.alignY = parseInt(this.options.alignY || '0');
-
- this.trackLength = this.maximumOffset() - this.minimumOffset();
-
- this.handleLength = this.isVertical() ? (this.handles[0].offsetHeight != 0 ? this.handles[0].offsetHeight
- : this.handles[0].style.height.replace(/px$/, "")) : (this.handles[0].offsetWidth != 0
- ? this.handles[0].offsetWidth : this.handles[0].style.width.replace(/px$/, ""));
-
- this.active = false;
- this.dragging = false;
- this.disabled = false;
-
- if ( this.options.disabled ) this.setDisabled();
-
- // Allowed values array
- this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
- if ( this.allowedValues )
- {
- this.minimum = this.allowedValues.min();
- this.maximum = this.allowedValues.max();
- }
-
- this.eventMouseDown = this.startDrag.bindAsEventListener(this);
- this.eventMouseUp = this.endDrag.bindAsEventListener(this);
- this.eventMouseMove = this.update.bindAsEventListener(this);
-
- // Initialize handles in reverse (make sure first handle is active)
- this.handles.each(function( h, i )
- {
- i = slider.handles.length - 1 - i;
- slider.setValue(parseFloat((slider.options.sliderValue instanceof Array ? slider.options.sliderValue[i]
- : slider.options.sliderValue) || slider.range.start), i);
- Element.makePositioned(h);
- // fix IE
- Event.observe(h, "mousedown", slider.eventMouseDown);
- });
-
- Event.observe(this.track, "mousedown", this.eventMouseDown);
- Event.observe(document, "mouseup", this.eventMouseUp);
- Event.observe(document, "mousemove", this.eventMouseMove);
-
- this.initialized = true;
- },
- dispose: function()
- {
- var slider = this;
- Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
- Event.stopObserving(document, "mouseup", this.eventMouseUp);
- Event.stopObserving(document, "mousemove", this.eventMouseMove);
- this.handles.each(function( h )
- {
- Event.stopObserving(h, "mousedown", slider.eventMouseDown);
- });
- },
- setDisabled: function()
- {
- this.disabled = true;
- },
- setEnabled: function()
- {
- this.disabled = false;
- },
- getNearestValue: function( value )
- {
- if ( this.allowedValues )
- {
- if ( value >= this.allowedValues.max() ) return(this.allowedValues.max());
- if ( value <= this.allowedValues.min() ) return(this.allowedValues.min());
-
- var offset = Math.abs(this.allowedValues[0] - value);
- var newValue = this.allowedValues[0];
- this.allowedValues.each(function( v )
- {
- var currentOffset = Math.abs(v - value);
- if ( currentOffset <= offset )
- {
- newValue = v;
- offset = currentOffset;
- }
- });
- return newValue;
- }
- if ( value > this.range.end ) return this.range.end;
- if ( value < this.range.start ) return this.range.start;
- return value;
- },
- setValue: function( sliderValue, handleIdx )
- {
- if ( !this.active )
- {
- this.activeHandleIdx = handleIdx || 0;
- this.activeHandle = this.handles[this.activeHandleIdx];
- this.updateStyles();
- }
- handleIdx = handleIdx || this.activeHandleIdx || 0;
- if ( this.initialized && this.restricted )
- {
- if ( (handleIdx > 0) && (sliderValue < this.values[handleIdx - 1]) )
- sliderValue = this.values[handleIdx - 1];
- if ( (handleIdx < (this.handles.length - 1)) && (sliderValue > this.values[handleIdx + 1]) )
- sliderValue = this.values[handleIdx + 1];
- }
- sliderValue = this.getNearestValue(sliderValue);
- this.values[handleIdx] = sliderValue;
- this.value = this.values[0];
- // assure backwards compat
-
- this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = this.translateToPx(sliderValue);
-
- this.drawSpans();
- if ( !this.dragging || !this.event ) this.updateFinished();
- },
- setValueBy: function( delta, handleIdx )
- {
- this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, handleIdx || this.activeHandleIdx ||
- 0);
- },
- translateToPx: function( value )
- {
- return Math.round(((this.trackLength - this.handleLength) / (this.range.end - this.range.start)) *
- (value - this.range.start)) + "px";
- },
- translateToValue: function( offset )
- {
- return ((offset / (this.trackLength - this.handleLength) * (this.range.end - this.range.start)) +
- this.range.start);
- },
- getRange: function( range )
- {
- var v = this.values.sortBy(Prototype.K);
- range = range || 0;
- return $R(v[range], v[range + 1]);
- },
- minimumOffset: function()
- {
- return(this.isVertical() ? this.alignY : this.alignX);
- },
- maximumOffset: function()
- {
- return(this.isVertical() ? (this.track.offsetHeight != 0 ? this.track.offsetHeight
- : this.track.style.height.replace(/px$/, "")) - this.alignY : (this.track.offsetWidth != 0
- ? this.track.offsetWidth : this.track.style.width.replace(/px$/, "")) - this.alignY);
- },
- isVertical: function()
- {
- return (this.axis == 'vertical');
- },
- drawSpans: function()
- {
- var slider = this;
- if ( this.spans )
- $R(0, this.spans.length - 1).each(function( r )
- {
- slider.setSpan(slider.spans[r], slider.getRange(r))
- });
- if ( this.options.startSpan )
- this.setSpan(this.options.startSpan, $R(0, this.values.length > 1 ? this.getRange(0).min() : this.value));
- if ( this.options.endSpan )
- this.setSpan(this.options.endSpan, $R(this.values.length > 1 ? this.getRange(this.spans.length - 1).max()
- : this.value, this.maximum));
- },
- setSpan: function( span, range )
- {
- if ( this.isVertical() )
- {
- span.style.top = this.translateToPx(range.start);
- span.style.height = this.translateToPx(range.end - range.start + this.range.start);
- }
- else
- {
- span.style.left = this.translateToPx(range.start);
- span.style.width = this.translateToPx(range.end - range.start + this.range.start);
- }
- },
- updateStyles: function()
- {
- this.handles.each(function( h )
- {
- Element.removeClassName(h, 'selected')
- });
- Element.addClassName(this.activeHandle, 'selected');
- },
- startDrag: function( event )
- {
- if ( Event.isLeftClick(event) )
- {
- if ( !this.disabled )
- {
- this.active = true;
-
- var handle = Event.element(event);
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var track = handle;
- if ( track == this.track )
- {
- var offsets = Position.cumulativeOffset(this.track);
- this.event = event;
- this.setValue(this.translateToValue((this.isVertical() ? pointer[1] - offsets[1] : pointer[0] -
- offsets[0]) -
- (this.handleLength / 2)));
- var offsets = Position.cumulativeOffset(this.activeHandle);
- this.offsetX = (pointer[0] - offsets[0]);
- this.offsetY = (pointer[1] - offsets[1]);
- }
- else
- {
- // find the handle (prevents issues with Safari)
- while ( (this.handles.indexOf(handle) == -1) && handle.parentNode )
- handle = handle.parentNode;
-
- this.activeHandle = handle;
- this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
- this.updateStyles();
-
- var offsets = Position.cumulativeOffset(this.activeHandle);
- this.offsetX = (pointer[0] - offsets[0]);
- this.offsetY = (pointer[1] - offsets[1]);
- }
- }
- Event.stop(event);
- }
- },
- update: function( event )
- {
- if ( this.active )
- {
- if ( !this.dragging ) this.dragging = true;
- this.draw(event);
- // fix AppleWebKit rendering
- if ( navigator.appVersion.indexOf('AppleWebKit') > 0 ) window.scrollBy(0, 0);
- Event.stop(event);
- }
- },
- draw: function( event )
- {
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var offsets = Position.cumulativeOffset(this.track);
- pointer[0] -= this.offsetX + offsets[0];
- pointer[1] -= this.offsetY + offsets[1];
- this.event = event;
- this.setValue(this.translateToValue(this.isVertical() ? pointer[1] : pointer[0]));
- if ( this.initialized && this.options.onSlide )
- this.options.onSlide(this.values.length > 1 ? this.values : this.value, this);
- },
- endDrag: function( event )
- {
- if ( this.active && this.dragging )
- {
- this.finishDrag(event, true);
- Event.stop(event);
- }
- this.active = false;
- this.dragging = false;
- },
- finishDrag: function( event, success )
- {
- this.active = false;
- this.dragging = false;
- this.updateFinished();
- },
- updateFinished: function()
- {
- if ( this.initialized && this.options.onChange )
- this.options.onChange(this.values.length > 1 ? this.values : this.value, this);
- this.event = null;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-// script.aculo.us unittest.js v1.6.4, Wed Sep 06 11:30:58 CEST 2006
-
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005 Jon Tirsen (http://www.tirsen.com)
-// (c) 2005 Michael Schuerig (http://www.schuerig.de/michael/)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-// experimental, Firefox-only
-Event.simulateMouse = function( element, eventName )
-{
- var options = Object.extend({
- pointerX: 0,
- pointerY: 0,
- buttons: 0
- }, arguments[2] || {});
- var oEvent = document.createEvent("MouseEvents");
- oEvent.initMouseEvent(eventName, true, true, document.defaultView, options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, false, false, false, false, 0, $(element));
-
- if ( this.mark ) Element.remove(this.mark);
- this.mark = document.createElement('div');
- this.mark.appendChild(document.createTextNode(" "));
- document.body.appendChild(this.mark);
- this.mark.style.position = 'absolute';
- this.mark.style.top = options.pointerY + "px";
- this.mark.style.left = options.pointerX + "px";
- this.mark.style.width = "5px";
- this.mark.style.height = "5px;";
- this.mark.style.borderTop = "1px solid red;"
- this.mark.style.borderLeft = "1px solid red;"
-
- if ( this.step )
- alert('[' + new Date().getTime().toString() + '] ' + eventName + '/' + Test.Unit.inspect(options));
-
- $(element).dispatchEvent(oEvent);
-};
-
-// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
-// You need to downgrade to 1.0.4 for now to get this working
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
-Event.simulateKey = function( element, eventName )
-{
- var options = Object.extend({
- ctrlKey: false,
- altKey: false,
- shiftKey: false,
- metaKey: false,
- keyCode: 0,
- charCode: 0
- }, arguments[2] || {});
-
- var oEvent = document.createEvent("KeyEvents");
- oEvent.initKeyEvent(eventName, true, true, window, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.keyCode, options.charCode);
- $(element).dispatchEvent(oEvent);
-};
-
-Event.simulateKeys = function( element, command )
-{
- for ( var i = 0; i < command.length; i++ )
- {
- Event.simulateKey(element, 'keypress', {charCode:command.charCodeAt(i)});
- }
-};
-
-var Test = {}
-Test.Unit = {};
-
-// security exception workaround
-Test.Unit.inspect = Object.inspect;
-
-Test.Unit.Logger = Class.create();
-Test.Unit.Logger.prototype = {
- initialize: function( log )
- {
- this.log = $(log);
- if ( this.log )
- {
- this._createLogTable();
- }
- },
- start: function( testName )
- {
- if ( !this.log ) return;
- this.testName = testName;
- this.lastLogLine = document.createElement('tr');
- this.statusCell = document.createElement('td');
- this.nameCell = document.createElement('td');
- this.nameCell.appendChild(document.createTextNode(testName));
- this.messageCell = document.createElement('td');
- this.lastLogLine.appendChild(this.statusCell);
- this.lastLogLine.appendChild(this.nameCell);
- this.lastLogLine.appendChild(this.messageCell);
- this.loglines.appendChild(this.lastLogLine);
- },
- finish: function( status, summary )
- {
- if ( !this.log ) return;
- this.lastLogLine.className = status;
- this.statusCell.innerHTML = status;
- this.messageCell.innerHTML = this._toHTML(summary);
- },
- message: function( message )
- {
- if ( !this.log ) return;
- this.messageCell.innerHTML = this._toHTML(message);
- },
- summary: function( summary )
- {
- if ( !this.log ) return;
- this.logsummary.innerHTML = this._toHTML(summary);
- },
- _createLogTable: function()
- {
- this.log.innerHTML = '<div id="logsummary"></div>' + '<table id="logtable">' +
- '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
- '<tbody id="loglines"></tbody>' + '</table>';
- this.logsummary = $('logsummary')
- this.loglines = $('loglines');
- },
- _toHTML: function( txt )
- {
- return txt.escapeHTML().replace(/\n/g, "<br/>");
- }
-}
-
-Test.Unit.Runner = Class.create();
-Test.Unit.Runner.prototype = {
- initialize: function( testcases )
- {
- this.options = Object.extend({
- testLog: 'testlog'
- }, arguments[1] || {});
- this.options.resultsURL = this.parseResultsURLQueryParameter();
- if ( this.options.testLog )
- {
- this.options.testLog = $(this.options.testLog) || null;
- }
- if ( this.options.tests )
- {
- this.tests = [];
- for ( var i = 0; i < this.options.tests.length; i++ )
- {
- if ( /^test/.test(this.options.tests[i]) )
- {
- this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
- }
- }
- }
- else
- {
- if ( this.options.test )
- {
- this.tests =
- [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
- }
- else
- {
- this.tests = [];
- for ( var testcase in testcases )
- {
- if ( /^test/.test(testcase) )
- {
- this.tests.push(new Test.Unit.Testcase(this.options.context ? ' -> ' +
- this.options.titles[testcase]
- : testcase, testcases[testcase], testcases["setup"], testcases["teardown"]));
- }
- }
- }
- }
- this.currentTest = 0;
- this.logger = new Test.Unit.Logger(this.options.testLog);
- setTimeout(this.runTests.bind(this), 1000);
- },
- parseResultsURLQueryParameter: function()
- {
- return window.location.search.parseQuery()["resultsURL"];
- },
-// Returns:
-// "ERROR" if there was an error,
-// "FAILURE" if there was a failure, or
-// "SUCCESS" if there was neither
- getResult: function()
- {
- var hasFailure = false;
- for ( var i = 0; i < this.tests.length; i++ )
- {
- if ( this.tests[i].errors > 0 )
- {
- return "ERROR";
- }
- if ( this.tests[i].failures > 0 )
- {
- hasFailure = true;
- }
- }
- if ( hasFailure )
- {
- return "FAILURE";
- }
- else
- {
- return "SUCCESS";
- }
- },
- postResults: function()
- {
- if ( this.options.resultsURL )
- {
- new Ajax.Request(this.options.resultsURL, { method: 'get', parameters: 'result=' +
- this.getResult(), asynchronous: false });
- }
- },
- runTests: function()
- {
- var test = this.tests[this.currentTest];
- if ( !test )
- {
- // finished!
- this.postResults();
- this.logger.summary(this.summary());
- return;
- }
- if ( !test.isWaiting )
- {
- this.logger.start(test.name);
- }
- test.run();
- if ( test.isWaiting )
- {
- this.logger.message("Waiting for " + test.timeToWait + "ms");
- setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
- }
- else
- {
- this.logger.finish(test.status(), test.summary());
- this.currentTest++;
- // tail recursive, hopefully the browser will skip the stackframe
- this.runTests();
- }
- },
- summary: function()
- {
- var assertions = 0;
- var failures = 0;
- var errors = 0;
- var messages = [];
- for ( var i = 0; i < this.tests.length; i++ )
- {
- assertions += this.tests[i].assertions;
- failures += this.tests[i].failures;
- errors += this.tests[i].errors;
- }
- return (
- (this.options.context ? this.options.context + ': ' : '') + this.tests.length + " tests, " + assertions +
- " assertions, " + failures + " failures, " + errors + " errors");
- }
-}
-
-Test.Unit.Assertions = Class.create();
-Test.Unit.Assertions.prototype = {
- initialize: function()
- {
- this.assertions = 0;
- this.failures = 0;
- this.errors = 0;
- this.messages = [];
- },
- summary: function()
- {
- return (
- this.assertions + " assertions, " + this.failures + " failures, " + this.errors + " errors" + "\n" +
- this.messages.join("\n"));
- },
- pass: function()
- {
- this.assertions++;
- },
- fail: function( message )
- {
- this.failures++;
- this.messages.push("Failure: " + message);
- },
- info: function( message )
- {
- this.messages.push("Info: " + message);
- },
- error: function( error )
- {
- this.errors++;
- this.messages.push(error.name + ": " + error.message + "(" + Test.Unit.inspect(error) + ")");
- },
- status: function()
- {
- if ( this.failures > 0 ) return 'failed';
- if ( this.errors > 0 ) return 'error';
- return 'passed';
- },
- assert: function( expression )
- {
- var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
- try
- {
- expression ? this.pass() : this.fail(message);
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertEqual: function( expected, actual )
- {
- var message = arguments[2] || "assertEqual";
- try
- {
- (expected == actual) ? this.pass() : this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
- '", actual "' + Test.Unit.inspect(actual) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertEnumEqual: function( expected, actual )
- {
- var message = arguments[2] || "assertEnumEqual";
- try
- {
- $A(expected).length == $A(actual).length && expected.zip(actual).all(function( pair )
- {
- return pair[0] == pair[1]
- }) ? this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + ', actual ' +
- Test.Unit.inspect(actual));
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertNotEqual: function( expected, actual )
- {
- var message = arguments[2] || "assertNotEqual";
- try
- {
- (expected != actual) ? this.pass() : this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertIdentical: function( expected, actual )
- {
- var message = arguments[2] || "assertIdentical";
- try
- {
- (expected === actual) ? this.pass() : this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
- '", actual "' + Test.Unit.inspect(actual) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertNotIdentical: function( expected, actual )
- {
- var message = arguments[2] || "assertNotIdentical";
- try
- {
- !(expected === actual) ? this.pass() : this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
- '", actual "' + Test.Unit.inspect(actual) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertNull: function( obj )
- {
- var message = arguments[1] || 'assertNull'
- try
- {
- (obj == null) ? this.pass() : this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertMatch: function( expected, actual )
- {
- var message = arguments[2] || 'assertMatch';
- var regex = new RegExp(expected);
- try
- {
- (regex.exec(actual)) ? this.pass() : this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) +
- ' did not match: ' + Test.Unit.inspect(actual) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertHidden: function( element )
- {
- var message = arguments[1] || 'assertHidden';
- this.assertEqual("none", element.style.display, message);
- },
- assertNotNull: function( object )
- {
- var message = arguments[1] || 'assertNotNull';
- this.assert(object != null, message);
- },
- assertType: function( expected, actual )
- {
- var message = arguments[2] || 'assertType';
- try
- {
- (actual.constructor == expected) ? this.pass() : this.fail(message + ': expected "' +
- Test.Unit.inspect(expected) + '", actual "' +
- (actual.constructor) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertNotOfType: function( expected, actual )
- {
- var message = arguments[2] || 'assertNotOfType';
- try
- {
- (actual.constructor != expected) ? this.pass() : this.fail(message + ': expected "' +
- Test.Unit.inspect(expected) + '", actual "' +
- (actual.constructor) + '"');
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertInstanceOf: function( expected, actual )
- {
- var message = arguments[2] || 'assertInstanceOf';
- try
- {
- (actual instanceof expected) ? this.pass() : this.fail(message +
- ": object was not an instance of the expected type");
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertNotInstanceOf: function( expected, actual )
- {
- var message = arguments[2] || 'assertNotInstanceOf';
- try
- {
- !(actual instanceof expected) ? this.pass() : this.fail(message +
- ": object was an instance of the not expected type");
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertRespondsTo: function( method, obj )
- {
- var message = arguments[2] || 'assertRespondsTo';
- try
- {
- (obj[method] && typeof obj[method] == 'function') ? this.pass() : this.fail(message +
- ": object doesn't respond to [" +
- method + "]");
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertReturnsTrue: function( method, obj )
- {
- var message = arguments[2] || 'assertReturnsTrue';
- try
- {
- var m = obj[method];
- if ( !m ) m = obj['is' + method.charAt(0).toUpperCase() + method.slice(1)];
- m() ? this.pass() : this.fail(message + ": method returned false");
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertReturnsFalse: function( method, obj )
- {
- var message = arguments[2] || 'assertReturnsFalse';
- try
- {
- var m = obj[method];
- if ( !m ) m = obj['is' + method.charAt(0).toUpperCase() + method.slice(1)];
- !m() ? this.pass() : this.fail(message + ": method returned true");
- }
- catch( e )
- {
- this.error(e);
- }
- },
- assertRaise: function( exceptionName, method )
- {
- var message = arguments[2] || 'assertRaise';
- try
- {
- method();
- this.fail(message + ": exception expected but none was raised");
- }
- catch( e )
- {
- (e.name == exceptionName) ? this.pass() : this.error(e);
- }
- },
- assertElementsMatch: function()
- {
- var expressions = $A(arguments), elements = $A(expressions.shift());
- if ( elements.length != expressions.length )
- {
- this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length +
- ' expressions');
- return false;
- }
- elements.zip(expressions).all(function( pair, index )
- {
- var element = $(pair.first()), expression = pair.last();
- if ( element.match(expression) ) return true;
- this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' +
- element.inspect());
- }.bind(this)) && this.pass();
- },
- assertElementMatches: function( element, expression )
- {
- this.assertElementsMatch([element], expression);
- },
- benchmark: function( operation, iterations )
- {
- var startAt = new Date();
- (iterations || 1).times(operation);
- var timeTaken = ((new Date()) - startAt);
- this.info((arguments[2] || 'Operation') + ' finished ' + iterations + ' iterations in ' + (timeTaken / 1000) +
- 's');
- return timeTaken;
- },
- _isVisible: function( element )
- {
- element = $(element);
- if ( !element.parentNode ) return true;
- this.assertNotNull(element);
- if ( element.style && Element.getStyle(element, 'display') == 'none' )
- return false;
-
- return this._isVisible(element.parentNode);
- },
- assertNotVisible: function( element )
- {
- this.assert(!this._isVisible(element), Test.Unit.inspect(element) +
- " was not hidden and didn't have a hidden parent either. " +
- ("" || arguments[1]));
- },
- assertVisible: function( element )
- {
- this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
- },
- benchmark: function( operation, iterations )
- {
- var startAt = new Date();
- (iterations || 1).times(operation);
- var timeTaken = ((new Date()) - startAt);
- this.info((arguments[2] || 'Operation') + ' finished ' + iterations + ' iterations in ' + (timeTaken / 1000) +
- 's');
- return timeTaken;
- }
-}
-
-Test.Unit.Testcase = Class.create();
-Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
- initialize: function( name, test, setup, teardown )
- {
- Test.Unit.Assertions.prototype.initialize.bind(this)();
- this.name = name;
-
- if ( typeof test == 'string' )
- {
- test = test.gsub(/(\.should[^\(]+\()/, '#{0}this,');
- test = test.gsub(/(\.should[^\(]+)\(this,\)/, '#{1}(this)');
- this.test = function()
- {
- eval('with(this){' + test + '}');
- }
- }
- else
- {
- this.test = test || function()
- {
- };
- }
-
- this.setup = setup || function()
- {
- };
- this.teardown = teardown || function()
- {
- };
- this.isWaiting = false;
- this.timeToWait = 1000;
- },
- wait: function( time, nextPart )
- {
- this.isWaiting = true;
- this.test = nextPart;
- this.timeToWait = time;
- },
- run: function()
- {
- try
- {
- try
- {
- if ( !this.isWaiting ) this.setup.bind(this)();
- this.isWaiting = false;
- this.test.bind(this)();
- }
- finally
- {
- if ( !this.isWaiting )
- {
- this.teardown.bind(this)();
- }
- }
- }
- catch( e )
- {
- this.error(e);
- }
- }
-});
-
-// *EXPERIMENTAL* BDD-style testing to please non-technical folk
-// This draws many ideas from RSpec http://rspec.rubyforge.org/
-
-Test.setupBDDExtensionMethods = function()
-{
- var METHODMAP = {
- shouldEqual: 'assertEqual',
- shouldNotEqual: 'assertNotEqual',
- shouldEqualEnum: 'assertEnumEqual',
- shouldBeA: 'assertType',
- shouldNotBeA: 'assertNotOfType',
- shouldBeAn: 'assertType',
- shouldNotBeAn: 'assertNotOfType',
- shouldBeNull: 'assertNull',
- shouldNotBeNull: 'assertNotNull',
-
- shouldBe: 'assertReturnsTrue',
- shouldNotBe: 'assertReturnsFalse',
- shouldRespondTo: 'assertRespondsTo'
- };
- Test.BDDMethods = {};
- for ( m in METHODMAP )
- {
- Test.BDDMethods[m] =
- eval('function(){' + 'var args = $A(arguments);' + 'var scope = args.shift();' + 'scope.' + METHODMAP[m] +
- '.apply(scope,(args || []).concat([this])); }');
- }
- [Array.prototype, String.prototype, Number.prototype].each(function( p )
- {
- Object.extend(p, Test.BDDMethods)
- });
-}
-
-Test.context = function( name, spec, log )
-{
- Test.setupBDDExtensionMethods();
-
- var compiledSpec = {};
- var titles = {};
- for ( specName in spec )
- {
- switch ( specName )
- {
- case "setup":
- case "teardown":
- compiledSpec[specName] = spec[specName];
- break;
- default:
- var testName = 'test' + specName.gsub(/\s+/, '-').camelize();
- var body = spec[specName].toString().split('\n').slice(1);
- if ( /^\{/.test(body[0]) ) body = body.slice(1);
- body.pop();
- body = body.map(function( statement )
- {
- return statement.strip()
- });
- compiledSpec[testName] = body.join('\n');
- titles[testName] = specName;
- }
- }
- new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
-};
\ No newline at end of file
+++ /dev/null
-<@ww.iterator value="parameters.list">
- <#if parameters.listKey?exists>
- <#assign itemKey = stack.findValue(parameters.listKey)/>
- <#else>
- <#assign itemKey = stack.findValue('top')/>
- </#if>
- <#if parameters.listValue?exists>
- <#assign itemValue = stack.findString(parameters.listValue)/>
- <#else>
- <#assign itemValue = stack.findString('top')/>
- </#if>
-<input type="checkbox" name="${parameters.name?html}" id="${parameters.id?html}${itemKey?html}"<#rt/>
-<#if tag.contains(parameters.nameValue, itemKey)>
- checked="checked"<#rt/>
-</#if>
-<#if itemKey?exists>
- value="${itemKey?html}"<#rt/>
-</#if>
-<#if parameters.disabled?default(false)>
- disabled="disabled"<#rt/>
-</#if>
-<#if parameters.tabindex?exists>
- tabindex="${parameters.tabindex?html}"<#rt/>
-</#if>
-<#if parameters.cssClass?exists>
- class="${parameters.cssClass?html}"<#rt/>
-</#if>
-<#if parameters.cssStyle?exists>
- style="${parameters.cssStyle?html}"<#rt/>
-</#if>
-<#if parameters.title?exists>
- title="${parameters.title?html}"<#rt/>
-</#if>
-<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
-/><#rt/>
-<label for="${parameters.id?html}${itemKey?html}"><#rt/>
- ${itemValue}<#t/>
-</label><br/>
-</@ww.iterator>
+++ /dev/null
-<@ww.iterator value="parameters.list">
- <#if parameters.listKey?exists>
- <#assign itemKey = stack.findValue(parameters.listKey)/>
- <#else>
- <#assign itemKey = stack.findValue('top')/>
- </#if>
- <#if parameters.listValue?exists>
- <#assign itemValue = stack.findString(parameters.listValue)/>
- <#else>
- <#assign itemValue = stack.findString('top')/>
- </#if>
-<input type="radio" name="${parameters.name?html}" id="${parameters.id?html}${itemKey?html}"<#rt/>
-<#if tag.contains(parameters.nameValue, itemKey)>
- checked="checked"<#rt/>
-</#if>
-<#if itemKey?exists>
- value="${itemKey?html}"<#rt/>
-</#if>
-<#if parameters.disabled?default(false)>
- disabled="disabled"<#rt/>
-</#if>
-<#if parameters.tabindex?exists>
- tabindex="${parameters.tabindex?html}"<#rt/>
-</#if>
-<#if parameters.cssClass?exists>
- class="${parameters.cssClass?html}"<#rt/>
-</#if>
-<#if parameters.cssStyle?exists>
- style="${parameters.cssStyle?html}"<#rt/>
-</#if>
-<#if parameters.title?exists>
- title="${parameters.title?html}"<#rt/>
-</#if>
-<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
-/><#rt/>
-<label for="${parameters.id?html}${itemKey?html}"><#rt/>
- ${itemValue}<#t/>
-</label><br/>
-</@ww.iterator>
+++ /dev/null
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-#
-
-parent = xhtml
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you 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.
- -->
-
-<plexus>
- <components>
- <!--
- | Logger manager
- -->
- <component>
- <role>org.codehaus.plexus.logging.LoggerManager</role>
- <implementation>org.codehaus.plexus.logging.log4j.Log4JLoggerManager</implementation>
- <lifecycle-handler>basic</lifecycle-handler>
-
- <configuration>
- <threshold>DEBUG</threshold>
- <default-appender>console</default-appender>
- <appenders>
- <appender>
- <id>console</id>
- <threshold>DEBUG</threshold>
- <type>org.apache.log4j.ConsoleAppender</type>
- <!-- <conversion-pattern>%d [%t] %-5p %-30c{1} - %m%n</conversion-pattern> -->
- <conversion-pattern>%r [%t] %-5p %c %x - %m%n</conversion-pattern>
- </appender>
- </appenders>
- <levels>
- <!-- Help identify bugs during testing -->
- <level>
- <hierarchy>org.apache.maven</hierarchy>
- <level>DEBUG</level>
- </level>
- <level>
- <hierarchy>org.codehaus.plexus.security</hierarchy>
- <level>DEBUG</level>
- </level>
- <!-- squelch noisy objects (for now) -->
- <level>
- <hierarchy>org.codehaus.plexus.mailsender.MailSender</hierarchy>
- <level>INFO</level>
- </level>
- <level>
- <hierarchy>org.quartz</hierarchy>
- <level>INFO</level>
- </level>
- <level>
- <hierarchy>org.apache.jasper</hierarchy>
- <level>INFO</level>
- </level>
- <level>
- <hierarchy>com.opensymphony.xwork</hierarchy>
- <level>DEBUG</level>
- </level>
- <level>
- <hierarchy>com.opensymphony.webwork</hierarchy>
- <level>DEBUG</level>
- </level>
- <level>
- <hierarchy>org.codehaus.plexus.PlexusContainer</hierarchy>
- <level>INFO</level>
- </level>
- <level>
- <hierarchy>JPOX</hierarchy>
- <level>WARN</level>
- </level>
- <level>
- <hierarchy>freemarker</hierarchy>
- <level>WARN</level>
- </level>
- <level>
- <hierarchy>freemarker</hierarchy>
- <level>WARN</level>
- </level>
- </levels>
- </configuration>
- </component>
-
-
- <component>
- <role>org.codehaus.plexus.jdo.JdoFactory</role>
- <role-hint>users</role-hint>
- <implementation>org.codehaus.plexus.jdo.DefaultConfigurableJdoFactory</implementation>
- <configuration>
-
- <!-- HSQLDB Configuration -->
- <!--
- NOTE: NO NOT USE THIS CONFIGURATION FOR A PRODUCTION SYSTEM.
- HSQLDB keeps all data in memory at all times.
-
- NOTE: JPOX 1.1.1 won't create the tables on start
- http://www.jpox.org/servlet/jira/browse/CORE-2946
- -->
-
- <!--
- <driverName>org.hsqldb.jdbcDriver</driverName>
- <url>jdbc:hsqldb:mem:test</url>
- <userName>sa</userName>
- <password></password>
- -->
-
- <!-- Apache Derby Configuration -->
- <driverName>org.apache.derby.jdbc.EmbeddedDriver</driverName>
- <url>jdbc:derby:${basedir}/target/repoaccess/database;create=true</url>
- <userName>sa</userName>
- <password></password>
-
- <!-- MySql Configuration -->
- <!--
- <driverName>com.mysql.jdbc.Driver</driverName>
- <url>jdbc:mysql://localhost/archiva</url>
- <userName>archiva</userName>
- <password>archiva</password>
- -->
-
- <!-- Postgresql Configuration -->
- <!--
- <driverName>org.postgresql.Driver</driverName>
- <url>jdbc:postgresql://localhost/continuum</url>
- <userName>username</userName>
- <password></password>
- -->
-
- <!-- JPOX and JDO configuration -->
- <persistenceManagerFactoryClass>org.jpox.PersistenceManagerFactoryImpl</persistenceManagerFactoryClass>
- <otherProperties>
- <property>
- <name>javax.jdo.PersistenceManagerFactoryClass</name>
- <value>org.jpox.PersistenceManagerFactoryImpl</value>
- </property>
- <property>
- <name>org.jpox.autoCreateSchema</name>
- <value>true</value>
- </property>
- <property>
- <name>org.jpox.autoStartMechanism</name>
- <value>SchemaTable</value>
- </property>
- <property>
- <name>org.jpox.autoStartMechanismMode</name>
- <value>Ignored</value>
- </property>
- <property>
- <name>org.jpox.validateTables</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.validateConstraints</name>
- <value>false</value>
- </property>
- <property>
- <name>org.jpox.transactionIsolation</name>
- <value>READ_UNCOMMITTED</value>
- </property>
- <property>
- <name>org.jpox.poid.transactionIsolation</name>
- <value>READ_UNCOMMITTED</value>
- </property>
- <property>
- <name>org.jpox.rdbms.dateTimezone</name>
- <value>JDK_DEFAULT_TIMEZONE</value>
- </property>
- </otherProperties>
- </configuration>
- </component>
-
- </components>
-</plexus>